blob: b33f943e629703f10a033e52906ae4c331e978e8 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
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.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#ifdef FEATURE_WLAN_TDLS
94#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053095#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053096#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080097#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053098#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070099#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700100
101#define g_mode_rates_size (12)
102#define a_mode_rates_size (8)
103#define FREQ_BASE_80211G (2407)
104#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700105#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530106#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700107#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800108 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700109
110#define HDD2GHZCHAN(freq, chan, flag) { \
111 .band = IEEE80211_BAND_2GHZ, \
112 .center_freq = (freq), \
113 .hw_value = (chan),\
114 .flags = (flag), \
115 .max_antenna_gain = 0 ,\
116 .max_power = 30, \
117}
118
119#define HDD5GHZCHAN(freq, chan, flag) { \
120 .band = IEEE80211_BAND_5GHZ, \
121 .center_freq = (freq), \
122 .hw_value = (chan),\
123 .flags = (flag), \
124 .max_antenna_gain = 0 ,\
125 .max_power = 30, \
126}
127
128#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
129{\
130 .bitrate = rate, \
131 .hw_value = rate_id, \
132 .flags = flag, \
133}
134
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530135#ifdef WLAN_FEATURE_VOWIFI_11R
136#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
137#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
138#endif
139
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530140#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530141#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530142
Sunil Duttc69bccb2014-05-26 21:30:20 +0530143#ifdef WLAN_FEATURE_LINK_LAYER_STATS
144/*
145 * Used to allocate the size of 4096 for the link layer stats.
146 * The size of 4096 is considered assuming that all data per
147 * respective event fit with in the limit.Please take a call
148 * on the limit based on the data requirements on link layer
149 * statistics.
150 */
151#define LL_STATS_EVENT_BUF_SIZE 4096
152#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530153#ifdef WLAN_FEATURE_EXTSCAN
154/*
155 * Used to allocate the size of 4096 for the EXTScan NL data.
156 * The size of 4096 is considered assuming that all data per
157 * respective event fit with in the limit.Please take a call
158 * on the limit based on the data requirements.
159 */
160
161#define EXTSCAN_EVENT_BUF_SIZE 4096
162#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
163#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530164
Atul Mittal115287b2014-07-08 13:26:33 +0530165/*EXT TDLS*/
166/*
167 * Used to allocate the size of 4096 for the TDLS.
168 * The size of 4096 is considered assuming that all data per
169 * respective event fit with in the limit.Please take a call
170 * on the limit based on the data requirements on link layer
171 * statistics.
172 */
173#define EXTTDLS_EVENT_BUF_SIZE 4096
174
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530175static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700176{
177 WLAN_CIPHER_SUITE_WEP40,
178 WLAN_CIPHER_SUITE_WEP104,
179 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800180#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700181#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
182 WLAN_CIPHER_SUITE_KRK,
183 WLAN_CIPHER_SUITE_CCMP,
184#else
185 WLAN_CIPHER_SUITE_CCMP,
186#endif
187#ifdef FEATURE_WLAN_WAPI
188 WLAN_CIPHER_SUITE_SMS4,
189#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700190#ifdef WLAN_FEATURE_11W
191 WLAN_CIPHER_SUITE_AES_CMAC,
192#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700193};
194
195static inline int is_broadcast_ether_addr(const u8 *addr)
196{
197 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
198 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
199}
200
201static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530202{
Jeff Johnson295189b2012-06-20 16:38:30 -0700203 HDD2GHZCHAN(2412, 1, 0) ,
204 HDD2GHZCHAN(2417, 2, 0) ,
205 HDD2GHZCHAN(2422, 3, 0) ,
206 HDD2GHZCHAN(2427, 4, 0) ,
207 HDD2GHZCHAN(2432, 5, 0) ,
208 HDD2GHZCHAN(2437, 6, 0) ,
209 HDD2GHZCHAN(2442, 7, 0) ,
210 HDD2GHZCHAN(2447, 8, 0) ,
211 HDD2GHZCHAN(2452, 9, 0) ,
212 HDD2GHZCHAN(2457, 10, 0) ,
213 HDD2GHZCHAN(2462, 11, 0) ,
214 HDD2GHZCHAN(2467, 12, 0) ,
215 HDD2GHZCHAN(2472, 13, 0) ,
216 HDD2GHZCHAN(2484, 14, 0) ,
217};
218
Jeff Johnson295189b2012-06-20 16:38:30 -0700219static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
220{
221 HDD2GHZCHAN(2412, 1, 0) ,
222 HDD2GHZCHAN(2437, 6, 0) ,
223 HDD2GHZCHAN(2462, 11, 0) ,
224};
Jeff Johnson295189b2012-06-20 16:38:30 -0700225
226static struct ieee80211_channel hdd_channels_5_GHZ[] =
227{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700228 HDD5GHZCHAN(4920, 240, 0) ,
229 HDD5GHZCHAN(4940, 244, 0) ,
230 HDD5GHZCHAN(4960, 248, 0) ,
231 HDD5GHZCHAN(4980, 252, 0) ,
232 HDD5GHZCHAN(5040, 208, 0) ,
233 HDD5GHZCHAN(5060, 212, 0) ,
234 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700235 HDD5GHZCHAN(5180, 36, 0) ,
236 HDD5GHZCHAN(5200, 40, 0) ,
237 HDD5GHZCHAN(5220, 44, 0) ,
238 HDD5GHZCHAN(5240, 48, 0) ,
239 HDD5GHZCHAN(5260, 52, 0) ,
240 HDD5GHZCHAN(5280, 56, 0) ,
241 HDD5GHZCHAN(5300, 60, 0) ,
242 HDD5GHZCHAN(5320, 64, 0) ,
243 HDD5GHZCHAN(5500,100, 0) ,
244 HDD5GHZCHAN(5520,104, 0) ,
245 HDD5GHZCHAN(5540,108, 0) ,
246 HDD5GHZCHAN(5560,112, 0) ,
247 HDD5GHZCHAN(5580,116, 0) ,
248 HDD5GHZCHAN(5600,120, 0) ,
249 HDD5GHZCHAN(5620,124, 0) ,
250 HDD5GHZCHAN(5640,128, 0) ,
251 HDD5GHZCHAN(5660,132, 0) ,
252 HDD5GHZCHAN(5680,136, 0) ,
253 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800254#ifdef FEATURE_WLAN_CH144
255 HDD5GHZCHAN(5720,144, 0) ,
256#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700257 HDD5GHZCHAN(5745,149, 0) ,
258 HDD5GHZCHAN(5765,153, 0) ,
259 HDD5GHZCHAN(5785,157, 0) ,
260 HDD5GHZCHAN(5805,161, 0) ,
261 HDD5GHZCHAN(5825,165, 0) ,
262};
263
264static struct ieee80211_rate g_mode_rates[] =
265{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530266 HDD_G_MODE_RATETAB(10, 0x1, 0),
267 HDD_G_MODE_RATETAB(20, 0x2, 0),
268 HDD_G_MODE_RATETAB(55, 0x4, 0),
269 HDD_G_MODE_RATETAB(110, 0x8, 0),
270 HDD_G_MODE_RATETAB(60, 0x10, 0),
271 HDD_G_MODE_RATETAB(90, 0x20, 0),
272 HDD_G_MODE_RATETAB(120, 0x40, 0),
273 HDD_G_MODE_RATETAB(180, 0x80, 0),
274 HDD_G_MODE_RATETAB(240, 0x100, 0),
275 HDD_G_MODE_RATETAB(360, 0x200, 0),
276 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700277 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530278};
Jeff Johnson295189b2012-06-20 16:38:30 -0700279
280static struct ieee80211_rate a_mode_rates[] =
281{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282 HDD_G_MODE_RATETAB(60, 0x10, 0),
283 HDD_G_MODE_RATETAB(90, 0x20, 0),
284 HDD_G_MODE_RATETAB(120, 0x40, 0),
285 HDD_G_MODE_RATETAB(180, 0x80, 0),
286 HDD_G_MODE_RATETAB(240, 0x100, 0),
287 HDD_G_MODE_RATETAB(360, 0x200, 0),
288 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700289 HDD_G_MODE_RATETAB(540, 0x800, 0),
290};
291
292static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
293{
294 .channels = hdd_channels_2_4_GHZ,
295 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
296 .band = IEEE80211_BAND_2GHZ,
297 .bitrates = g_mode_rates,
298 .n_bitrates = g_mode_rates_size,
299 .ht_cap.ht_supported = 1,
300 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
301 | IEEE80211_HT_CAP_GRN_FLD
302 | IEEE80211_HT_CAP_DSSSCCK40
303 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
304 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
305 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
306 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
307 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
308 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
309};
310
Jeff Johnson295189b2012-06-20 16:38:30 -0700311static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
312{
313 .channels = hdd_social_channels_2_4_GHZ,
314 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
315 .band = IEEE80211_BAND_2GHZ,
316 .bitrates = g_mode_rates,
317 .n_bitrates = g_mode_rates_size,
318 .ht_cap.ht_supported = 1,
319 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
320 | IEEE80211_HT_CAP_GRN_FLD
321 | IEEE80211_HT_CAP_DSSSCCK40
322 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
323 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
324 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
325 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
326 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
327 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
328};
Jeff Johnson295189b2012-06-20 16:38:30 -0700329
330static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
331{
332 .channels = hdd_channels_5_GHZ,
333 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
334 .band = IEEE80211_BAND_5GHZ,
335 .bitrates = a_mode_rates,
336 .n_bitrates = a_mode_rates_size,
337 .ht_cap.ht_supported = 1,
338 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
339 | IEEE80211_HT_CAP_GRN_FLD
340 | IEEE80211_HT_CAP_DSSSCCK40
341 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
342 | IEEE80211_HT_CAP_SGI_40
343 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
344 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
345 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
346 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
347 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
348 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
349};
350
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530351/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700352 TX/RX direction for each kind of interface */
353static const struct ieee80211_txrx_stypes
354wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
355 [NL80211_IFTYPE_STATION] = {
356 .tx = 0xffff,
357 .rx = BIT(SIR_MAC_MGMT_ACTION) |
358 BIT(SIR_MAC_MGMT_PROBE_REQ),
359 },
360 [NL80211_IFTYPE_AP] = {
361 .tx = 0xffff,
362 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
363 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
364 BIT(SIR_MAC_MGMT_PROBE_REQ) |
365 BIT(SIR_MAC_MGMT_DISASSOC) |
366 BIT(SIR_MAC_MGMT_AUTH) |
367 BIT(SIR_MAC_MGMT_DEAUTH) |
368 BIT(SIR_MAC_MGMT_ACTION),
369 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700370 [NL80211_IFTYPE_ADHOC] = {
371 .tx = 0xffff,
372 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
373 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_PROBE_REQ) |
375 BIT(SIR_MAC_MGMT_DISASSOC) |
376 BIT(SIR_MAC_MGMT_AUTH) |
377 BIT(SIR_MAC_MGMT_DEAUTH) |
378 BIT(SIR_MAC_MGMT_ACTION),
379 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700380 [NL80211_IFTYPE_P2P_CLIENT] = {
381 .tx = 0xffff,
382 .rx = BIT(SIR_MAC_MGMT_ACTION) |
383 BIT(SIR_MAC_MGMT_PROBE_REQ),
384 },
385 [NL80211_IFTYPE_P2P_GO] = {
386 /* This is also same as for SoftAP */
387 .tx = 0xffff,
388 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
389 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
390 BIT(SIR_MAC_MGMT_PROBE_REQ) |
391 BIT(SIR_MAC_MGMT_DISASSOC) |
392 BIT(SIR_MAC_MGMT_AUTH) |
393 BIT(SIR_MAC_MGMT_DEAUTH) |
394 BIT(SIR_MAC_MGMT_ACTION),
395 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700396};
397
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800398#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800399static const struct ieee80211_iface_limit
400wlan_hdd_iface_limit[] = {
401 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800402 /* max = 3 ; Our driver create two interfaces during driver init
403 * wlan0 and p2p0 interfaces. p2p0 is considered as station
404 * interface until a group is formed. In JB architecture, once the
405 * group is formed, interface type of p2p0 is changed to P2P GO or
406 * Client.
407 * When supplicant remove the group, it first issue a set interface
408 * cmd to change the mode back to Station. In JB this works fine as
409 * we advertize two station type interface during driver init.
410 * Some vendors create separate interface for P2P GO/Client,
411 * after group formation(Third one). But while group remove
412 * supplicant first tries to change the mode(3rd interface) to STATION
413 * But as we advertized only two sta type interfaces nl80211 was
414 * returning error for the third one which was leading to failure in
415 * delete interface. Ideally while removing the group, supplicant
416 * should not try to change the 3rd interface mode to Station type.
417 * Till we get a fix in wpa_supplicant, we advertize max STA
418 * interface type to 3
419 */
420 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800421 .types = BIT(NL80211_IFTYPE_STATION),
422 },
423 {
424 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700425 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800426 },
427 {
428 .max = 1,
429 .types = BIT(NL80211_IFTYPE_P2P_GO) |
430 BIT(NL80211_IFTYPE_P2P_CLIENT),
431 },
432};
433
434/* By default, only single channel concurrency is allowed */
435static struct ieee80211_iface_combination
436wlan_hdd_iface_combination = {
437 .limits = wlan_hdd_iface_limit,
438 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800439 /*
440 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
441 * and p2p0 interfaces during driver init
442 * Some vendors create separate interface for P2P operations.
443 * wlan0: STA interface
444 * p2p0: P2P Device interface, action frames goes
445 * through this interface.
446 * p2p-xx: P2P interface, After GO negotiation this interface is
447 * created for p2p operations(GO/CLIENT interface).
448 */
449 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800450 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
451 .beacon_int_infra_match = false,
452};
453#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800454
Jeff Johnson295189b2012-06-20 16:38:30 -0700455static struct cfg80211_ops wlan_hdd_cfg80211_ops;
456
457/* Data rate 100KBPS based on IE Index */
458struct index_data_rate_type
459{
460 v_U8_t beacon_rate_index;
461 v_U16_t supported_rate[4];
462};
463
464/* 11B, 11G Rate table include Basic rate and Extended rate
465 The IDX field is the rate index
466 The HI field is the rate when RSSI is strong or being ignored
467 (in this case we report actual rate)
468 The MID field is the rate when RSSI is moderate
469 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
470 The LO field is the rate when RSSI is low
471 (in this case we don't report rates, actual current rate used)
472 */
473static const struct
474{
475 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700476 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700477} supported_data_rate[] =
478{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700479/* IDX HI HM LM LO (RSSI-based index */
480 {2, { 10, 10, 10, 0}},
481 {4, { 20, 20, 10, 0}},
482 {11, { 55, 20, 10, 0}},
483 {12, { 60, 55, 20, 0}},
484 {18, { 90, 55, 20, 0}},
485 {22, {110, 55, 20, 0}},
486 {24, {120, 90, 60, 0}},
487 {36, {180, 120, 60, 0}},
488 {44, {220, 180, 60, 0}},
489 {48, {240, 180, 90, 0}},
490 {66, {330, 180, 90, 0}},
491 {72, {360, 240, 90, 0}},
492 {96, {480, 240, 120, 0}},
493 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700494};
495
496/* MCS Based rate table */
497static struct index_data_rate_type supported_mcs_rate[] =
498{
499/* MCS L20 L40 S20 S40 */
500 {0, {65, 135, 72, 150}},
501 {1, {130, 270, 144, 300}},
502 {2, {195, 405, 217, 450}},
503 {3, {260, 540, 289, 600}},
504 {4, {390, 810, 433, 900}},
505 {5, {520, 1080, 578, 1200}},
506 {6, {585, 1215, 650, 1350}},
507 {7, {650, 1350, 722, 1500}}
508};
509
Leo Chang6f8870f2013-03-26 18:11:36 -0700510#ifdef WLAN_FEATURE_11AC
511
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530512#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700513
514struct index_vht_data_rate_type
515{
516 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530517 v_U16_t supported_VHT80_rate[2];
518 v_U16_t supported_VHT40_rate[2];
519 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700520};
521
522typedef enum
523{
524 DATA_RATE_11AC_MAX_MCS_7,
525 DATA_RATE_11AC_MAX_MCS_8,
526 DATA_RATE_11AC_MAX_MCS_9,
527 DATA_RATE_11AC_MAX_MCS_NA
528} eDataRate11ACMaxMcs;
529
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530530/* SSID broadcast type */
531typedef enum eSSIDBcastType
532{
533 eBCAST_UNKNOWN = 0,
534 eBCAST_NORMAL = 1,
535 eBCAST_HIDDEN = 2,
536} tSSIDBcastType;
537
Leo Chang6f8870f2013-03-26 18:11:36 -0700538/* MCS Based VHT rate table */
539static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
540{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530541/* MCS L80 S80 L40 S40 L20 S40*/
542 {0, {293, 325}, {135, 150}, {65, 72}},
543 {1, {585, 650}, {270, 300}, {130, 144}},
544 {2, {878, 975}, {405, 450}, {195, 217}},
545 {3, {1170, 1300}, {540, 600}, {260, 289}},
546 {4, {1755, 1950}, {810, 900}, {390, 433}},
547 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
548 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
549 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
550 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
551 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700552};
553#endif /* WLAN_FEATURE_11AC */
554
c_hpothu79aab322014-07-14 21:11:01 +0530555/*array index points to MCS and array value points respective rssi*/
556static int rssiMcsTbl[][10] =
557{
558/*MCS 0 1 2 3 4 5 6 7 8 9*/
559 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
560 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
561 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
562};
563
Jeff Johnson295189b2012-06-20 16:38:30 -0700564extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530565#ifdef FEATURE_WLAN_SCAN_PNO
566static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
567#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700568
Leo Chang9056f462013-08-01 19:21:11 -0700569#ifdef WLAN_NL80211_TESTMODE
570enum wlan_hdd_tm_attr
571{
572 WLAN_HDD_TM_ATTR_INVALID = 0,
573 WLAN_HDD_TM_ATTR_CMD = 1,
574 WLAN_HDD_TM_ATTR_DATA = 2,
575 WLAN_HDD_TM_ATTR_TYPE = 3,
576 /* keep last */
577 WLAN_HDD_TM_ATTR_AFTER_LAST,
578 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
579};
580
581enum wlan_hdd_tm_cmd
582{
583 WLAN_HDD_TM_CMD_WLAN_HB = 1,
584};
585
586#define WLAN_HDD_TM_DATA_MAX_LEN 5000
587
588static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
589{
590 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
591 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
592 .len = WLAN_HDD_TM_DATA_MAX_LEN },
593};
594#endif /* WLAN_NL80211_TESTMODE */
595
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800596#ifdef FEATURE_WLAN_CH_AVOID
597/*
598 * FUNCTION: wlan_hdd_send_avoid_freq_event
599 * This is called when wlan driver needs to send vendor specific
600 * avoid frequency range event to userspace
601 */
602int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
603 tHddAvoidFreqList *pAvoidFreqList)
604{
605 struct sk_buff *vendor_event;
606
607 ENTER();
608
609 if (!pHddCtx)
610 {
611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
612 "%s: HDD context is null", __func__);
613 return -1;
614 }
615
616 if (!pAvoidFreqList)
617 {
618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
619 "%s: pAvoidFreqList is null", __func__);
620 return -1;
621 }
622
623 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
624 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530625 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800626 GFP_KERNEL);
627 if (!vendor_event)
628 {
629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
630 "%s: cfg80211_vendor_event_alloc failed", __func__);
631 return -1;
632 }
633
634 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
635 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
636
637 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
638
639 EXIT();
640 return 0;
641}
642#endif /* FEATURE_WLAN_CH_AVOID */
643
Sunil Duttc69bccb2014-05-26 21:30:20 +0530644#ifdef WLAN_FEATURE_LINK_LAYER_STATS
645
646static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
647 struct sk_buff *vendor_event)
648{
649 if (nla_put_u8(vendor_event,
650 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
651 stats->rate.preamble) ||
652 nla_put_u8(vendor_event,
653 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
654 stats->rate.nss) ||
655 nla_put_u8(vendor_event,
656 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
657 stats->rate.bw) ||
658 nla_put_u8(vendor_event,
659 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
660 stats->rate.rateMcsIdx) ||
661 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
662 stats->rate.bitrate ) ||
663 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
664 stats->txMpdu ) ||
665 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
666 stats->rxMpdu ) ||
667 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
668 stats->mpduLost ) ||
669 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
670 stats->retries) ||
671 nla_put_u32(vendor_event,
672 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
673 stats->retriesShort ) ||
674 nla_put_u32(vendor_event,
675 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
676 stats->retriesLong))
677 {
678 hddLog(VOS_TRACE_LEVEL_ERROR,
679 FL("QCA_WLAN_VENDOR_ATTR put fail"));
680 return FALSE;
681 }
682 return TRUE;
683}
684
685static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
686 struct sk_buff *vendor_event)
687{
688 u32 i = 0;
689 struct nlattr *rateInfo;
690 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
691 stats->type) ||
692 nla_put(vendor_event,
693 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
694 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
695 nla_put_u32(vendor_event,
696 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
697 stats->capabilities) ||
698 nla_put_u32(vendor_event,
699 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
700 stats->numRate))
701 {
702 hddLog(VOS_TRACE_LEVEL_ERROR,
703 FL("QCA_WLAN_VENDOR_ATTR put fail"));
704 goto error;
705 }
706
707 rateInfo = nla_nest_start(vendor_event,
708 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530709 if(!rateInfo)
710 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530711 for (i = 0; i < stats->numRate; i++)
712 {
713 struct nlattr *rates;
714 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
715 stats->rateStats +
716 (i * sizeof(tSirWifiRateStat)));
717 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530718 if(!rates)
719 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530720
721 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
722 {
723 hddLog(VOS_TRACE_LEVEL_ERROR,
724 FL("QCA_WLAN_VENDOR_ATTR put fail"));
725 return FALSE;
726 }
727 nla_nest_end(vendor_event, rates);
728 }
729 nla_nest_end(vendor_event, rateInfo);
730
731 return TRUE;
732error:
733 return FALSE;
734}
735
736static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
737 struct sk_buff *vendor_event)
738{
739 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
740 stats->ac ) ||
741 nla_put_u32(vendor_event,
742 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
743 stats->txMpdu ) ||
744 nla_put_u32(vendor_event,
745 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
746 stats->rxMpdu ) ||
747 nla_put_u32(vendor_event,
748 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
749 stats->txMcast ) ||
750 nla_put_u32(vendor_event,
751 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
752 stats->rxMcast ) ||
753 nla_put_u32(vendor_event,
754 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
755 stats->rxAmpdu ) ||
756 nla_put_u32(vendor_event,
757 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
758 stats->txAmpdu ) ||
759 nla_put_u32(vendor_event,
760 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
761 stats->mpduLost )||
762 nla_put_u32(vendor_event,
763 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
764 stats->retries ) ||
765 nla_put_u32(vendor_event,
766 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
767 stats->retriesShort ) ||
768 nla_put_u32(vendor_event,
769 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
770 stats->retriesLong ) ||
771 nla_put_u32(vendor_event,
772 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
773 stats->contentionTimeMin ) ||
774 nla_put_u32(vendor_event,
775 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
776 stats->contentionTimeMax ) ||
777 nla_put_u32(vendor_event,
778 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
779 stats->contentionTimeAvg ) ||
780 nla_put_u32(vendor_event,
781 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
782 stats->contentionNumSamples ))
783 {
784 hddLog(VOS_TRACE_LEVEL_ERROR,
785 FL("QCA_WLAN_VENDOR_ATTR put fail") );
786 return FALSE;
787 }
788 return TRUE;
789}
790
791static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
792 struct sk_buff *vendor_event)
793{
Dino Myclec8f3f332014-07-21 16:48:27 +0530794 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530795 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
796 nla_put(vendor_event,
797 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
798 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
799 nla_put_u32(vendor_event,
800 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
801 stats->state ) ||
802 nla_put_u32(vendor_event,
803 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
804 stats->roaming ) ||
805 nla_put_u32(vendor_event,
806 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
807 stats->capabilities ) ||
808 nla_put(vendor_event,
809 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
810 strlen(stats->ssid), stats->ssid) ||
811 nla_put(vendor_event,
812 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
813 WNI_CFG_BSSID_LEN, stats->bssid) ||
814 nla_put(vendor_event,
815 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
816 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
817 nla_put(vendor_event,
818 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
819 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
820 )
821 {
822 hddLog(VOS_TRACE_LEVEL_ERROR,
823 FL("QCA_WLAN_VENDOR_ATTR put fail") );
824 return FALSE;
825 }
826 return TRUE;
827}
828
Dino Mycle3b9536d2014-07-09 22:05:24 +0530829static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
830 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530831 struct sk_buff *vendor_event)
832{
833 int i = 0;
834 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530835 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
836 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530837 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530838
Sunil Duttc69bccb2014-05-26 21:30:20 +0530839 if (FALSE == put_wifi_interface_info(
840 &pWifiIfaceStat->info,
841 vendor_event))
842 {
843 hddLog(VOS_TRACE_LEVEL_ERROR,
844 FL("QCA_WLAN_VENDOR_ATTR put fail") );
845 return FALSE;
846
847 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530848 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
849 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
850 if (NULL == pWifiIfaceStatTL)
851 {
852 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
853 return FALSE;
854 }
855
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530856 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
857 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
858 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
859 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
860
861 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
862 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
863 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
864 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530865
866 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
867 {
868 if (VOS_STATUS_SUCCESS ==
869 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
870 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
871 {
872 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
873 * obtained from TL structure
874 */
875
876 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
877 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530878 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
879
Srinivas Dasari98947432014-11-07 19:41:24 +0530880 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
881 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
882 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
883 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
884 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
885 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
886 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
887 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530888
Srinivas Dasari98947432014-11-07 19:41:24 +0530889 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
890 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
891 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
892 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
893 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
894 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
895 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
896 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530897
Srinivas Dasari98947432014-11-07 19:41:24 +0530898 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
899 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
900 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
901 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
902 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
903 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
904 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
905 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530906 }
907 else
908 {
909 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
910 }
911
Dino Mycle3b9536d2014-07-09 22:05:24 +0530912 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
913 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
914 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
915 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
916 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
917 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
918 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
919 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
920 }
921 else
922 {
923 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
924 }
925
926
Sunil Duttc69bccb2014-05-26 21:30:20 +0530927
928 if (nla_put_u32(vendor_event,
929 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
930 pWifiIfaceStat->beaconRx) ||
931 nla_put_u32(vendor_event,
932 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
933 pWifiIfaceStat->mgmtRx) ||
934 nla_put_u32(vendor_event,
935 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
936 pWifiIfaceStat->mgmtActionRx) ||
937 nla_put_u32(vendor_event,
938 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
939 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530940 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530941 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
942 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530943 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530944 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
945 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530946 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530947 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
948 pWifiIfaceStat->rssiAck))
949 {
950 hddLog(VOS_TRACE_LEVEL_ERROR,
951 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530952 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530953 return FALSE;
954 }
955
956 wmmInfo = nla_nest_start(vendor_event,
957 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530958 if(!wmmInfo)
959 {
960 vos_mem_free(pWifiIfaceStatTL);
961 return FALSE;
962 }
Sunil Duttc69bccb2014-05-26 21:30:20 +0530963 for (i = 0; i < WIFI_AC_MAX; i++)
964 {
965 struct nlattr *wmmStats;
966 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530967 if(!wmmStats)
968 {
969 vos_mem_free(pWifiIfaceStatTL);
970 return FALSE;
971 }
Sunil Duttc69bccb2014-05-26 21:30:20 +0530972 if (FALSE == put_wifi_wmm_ac_stat(
973 &pWifiIfaceStat->AccessclassStats[i],
974 vendor_event))
975 {
976 hddLog(VOS_TRACE_LEVEL_ERROR,
977 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530978 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530979 return FALSE;
980 }
981
982 nla_nest_end(vendor_event, wmmStats);
983 }
984 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +0530985 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530986 return TRUE;
987}
988
989static tSirWifiInterfaceMode
990 hdd_map_device_to_ll_iface_mode ( int deviceMode )
991{
992 switch (deviceMode)
993 {
994 case WLAN_HDD_INFRA_STATION:
995 return WIFI_INTERFACE_STA;
996 case WLAN_HDD_SOFTAP:
997 return WIFI_INTERFACE_SOFTAP;
998 case WLAN_HDD_P2P_CLIENT:
999 return WIFI_INTERFACE_P2P_CLIENT;
1000 case WLAN_HDD_P2P_GO:
1001 return WIFI_INTERFACE_P2P_GO;
1002 case WLAN_HDD_IBSS:
1003 return WIFI_INTERFACE_IBSS;
1004 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301005 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301006 }
1007}
1008
1009static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1010 tpSirWifiInterfaceInfo pInfo)
1011{
1012 v_U8_t *staMac = NULL;
1013 hdd_station_ctx_t *pHddStaCtx;
1014 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1015 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1016
1017 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1018
1019 vos_mem_copy(pInfo->macAddr,
1020 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1021
1022 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1023 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1024 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1025 {
1026 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1027 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1028 {
1029 pInfo->state = WIFI_DISCONNECTED;
1030 }
1031 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1032 {
1033 hddLog(VOS_TRACE_LEVEL_ERROR,
1034 "%s: Session ID %d, Connection is in progress", __func__,
1035 pAdapter->sessionId);
1036 pInfo->state = WIFI_ASSOCIATING;
1037 }
1038 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1039 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1040 {
1041 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1042 hddLog(VOS_TRACE_LEVEL_ERROR,
1043 "%s: client " MAC_ADDRESS_STR
1044 " is in the middle of WPS/EAPOL exchange.", __func__,
1045 MAC_ADDR_ARRAY(staMac));
1046 pInfo->state = WIFI_AUTHENTICATING;
1047 }
1048 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1049 {
1050 pInfo->state = WIFI_ASSOCIATED;
1051 vos_mem_copy(pInfo->bssid,
1052 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1053 vos_mem_copy(pInfo->ssid,
1054 pHddStaCtx->conn_info.SSID.SSID.ssId,
1055 pHddStaCtx->conn_info.SSID.SSID.length);
1056 //NULL Terminate the string.
1057 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1058 }
1059 }
1060 vos_mem_copy(pInfo->countryStr,
1061 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1062
1063 vos_mem_copy(pInfo->apCountryStr,
1064 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1065
1066 return TRUE;
1067}
1068
1069/*
1070 * hdd_link_layer_process_peer_stats () - This function is called after
1071 * receiving Link Layer Peer statistics from FW.This function converts
1072 * the firmware data to the NL data and sends the same to the kernel/upper
1073 * layers.
1074 */
1075static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1076 v_VOID_t *pData)
1077{
1078 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1079 tpSirWifiRateStat pWifiRateStat;
1080 tpSirWifiPeerStat pWifiPeerStat;
1081 tpSirWifiPeerInfo pWifiPeerInfo;
1082 struct nlattr *peerInfo;
1083 struct sk_buff *vendor_event;
1084 int status, i;
1085
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301086 ENTER();
1087
Sunil Duttc69bccb2014-05-26 21:30:20 +05301088 status = wlan_hdd_validate_context(pHddCtx);
1089 if (0 != status)
1090 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301091 return;
1092 }
1093
1094 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1095
1096 hddLog(VOS_TRACE_LEVEL_INFO,
1097 "LL_STATS_PEER_ALL : numPeers %u",
1098 pWifiPeerStat->numPeers);
1099 {
1100 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1101 {
1102 pWifiPeerInfo = (tpSirWifiPeerInfo)
1103 ((uint8 *)pWifiPeerStat->peerInfo +
1104 ( i * sizeof(tSirWifiPeerInfo)));
1105
Dasari Srinivas1be0c4e2014-10-19 13:03:41 +05301106 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) {
1107 pWifiPeerInfo->type = WIFI_PEER_AP;
1108 }
1109 if (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
1110 pWifiPeerInfo->type = WIFI_PEER_P2P_GO;
1111 }
1112
Sunil Duttc69bccb2014-05-26 21:30:20 +05301113 hddLog(VOS_TRACE_LEVEL_INFO,
1114 " %d) LL_STATS Channel Stats "
1115 " Peer Type %u "
1116 " peerMacAddress %pM "
1117 " capabilities 0x%x "
1118 " numRate %u ",
1119 i,
1120 pWifiPeerInfo->type,
1121 pWifiPeerInfo->peerMacAddress,
1122 pWifiPeerInfo->capabilities,
1123 pWifiPeerInfo->numRate);
1124 {
1125 int j;
1126 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1127 {
1128 pWifiRateStat = (tpSirWifiRateStat)
1129 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1130 ( j * sizeof(tSirWifiRateStat)));
1131
1132 hddLog(VOS_TRACE_LEVEL_INFO,
1133 " peer Rate Stats "
1134 " preamble %u "
1135 " nss %u "
1136 " bw %u "
1137 " rateMcsIdx %u "
1138 " reserved %u "
1139 " bitrate %u "
1140 " txMpdu %u "
1141 " rxMpdu %u "
1142 " mpduLost %u "
1143 " retries %u "
1144 " retriesShort %u "
1145 " retriesLong %u",
1146 pWifiRateStat->rate.preamble,
1147 pWifiRateStat->rate.nss,
1148 pWifiRateStat->rate.bw,
1149 pWifiRateStat->rate.rateMcsIdx,
1150 pWifiRateStat->rate.reserved,
1151 pWifiRateStat->rate.bitrate,
1152 pWifiRateStat->txMpdu,
1153 pWifiRateStat->rxMpdu,
1154 pWifiRateStat->mpduLost,
1155 pWifiRateStat->retries,
1156 pWifiRateStat->retriesShort,
1157 pWifiRateStat->retriesLong);
1158 }
1159 }
1160 }
1161 }
1162
1163 /*
1164 * Allocate a size of 4096 for the peer stats comprising
1165 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1166 * sizeof (tSirWifiRateStat).Each field is put with an
1167 * NL attribute.The size of 4096 is considered assuming
1168 * that number of rates shall not exceed beyond 50 with
1169 * the sizeof (tSirWifiRateStat) being 32.
1170 */
1171 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1172 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1173 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1174 GFP_KERNEL);
1175 if (!vendor_event)
1176 {
1177 hddLog(VOS_TRACE_LEVEL_ERROR,
1178 "%s: cfg80211_vendor_event_alloc failed",
1179 __func__);
1180 return;
1181 }
1182 if (nla_put_u32(vendor_event,
1183 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1184 pWifiPeerStat->numPeers))
1185 {
1186 hddLog(VOS_TRACE_LEVEL_ERROR,
1187 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1188 kfree_skb(vendor_event);
1189 return;
1190 }
1191
1192 peerInfo = nla_nest_start(vendor_event,
1193 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301194 if(!peerInfo)
1195 {
1196 hddLog(VOS_TRACE_LEVEL_ERROR,
1197 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1198 __func__);
1199 kfree_skb(vendor_event);
1200 return;
1201 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301202
1203 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1204 pWifiPeerStat->peerInfo);
1205
1206 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1207 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301208 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301209 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301210
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301211 if(!peers)
1212 {
1213 hddLog(VOS_TRACE_LEVEL_ERROR,
1214 "%s: peer stats put fail",
1215 __func__);
1216 kfree_skb(vendor_event);
1217 return;
1218 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301219 if (FALSE == put_wifi_peer_info(
1220 pWifiPeerInfo, vendor_event))
1221 {
1222 hddLog(VOS_TRACE_LEVEL_ERROR,
1223 "%s: put_wifi_peer_info put fail", __func__);
1224 kfree_skb(vendor_event);
1225 return;
1226 }
1227
1228 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1229 pWifiPeerStat->peerInfo +
1230 (i * sizeof(tSirWifiPeerInfo)) +
1231 (numRate * sizeof (tSirWifiRateStat)));
1232 nla_nest_end(vendor_event, peers);
1233 }
1234 nla_nest_end(vendor_event, peerInfo);
1235 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301236
1237 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301238}
1239
1240/*
1241 * hdd_link_layer_process_iface_stats () - This function is called after
1242 * receiving Link Layer Interface statistics from FW.This function converts
1243 * the firmware data to the NL data and sends the same to the kernel/upper
1244 * layers.
1245 */
1246static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1247 v_VOID_t *pData)
1248{
1249 tpSirWifiIfaceStat pWifiIfaceStat;
1250 struct sk_buff *vendor_event;
1251 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1252 int status;
1253
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301254 ENTER();
1255
Sunil Duttc69bccb2014-05-26 21:30:20 +05301256 status = wlan_hdd_validate_context(pHddCtx);
1257 if (0 != status)
1258 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301259 return;
1260 }
1261 /*
1262 * Allocate a size of 4096 for the interface stats comprising
1263 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1264 * assuming that all these fit with in the limit.Please take
1265 * a call on the limit based on the data requirements on
1266 * interface statistics.
1267 */
1268 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1269 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1270 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1271 GFP_KERNEL);
1272 if (!vendor_event)
1273 {
1274 hddLog(VOS_TRACE_LEVEL_ERROR,
1275 FL("cfg80211_vendor_event_alloc failed") );
1276 return;
1277 }
1278
1279 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1280
Dino Mycle3b9536d2014-07-09 22:05:24 +05301281
1282 if (FALSE == hdd_get_interface_info( pAdapter,
1283 &pWifiIfaceStat->info))
1284 {
1285 hddLog(VOS_TRACE_LEVEL_ERROR,
1286 FL("hdd_get_interface_info get fail") );
1287 kfree_skb(vendor_event);
1288 return;
1289 }
1290
1291 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1292 vendor_event))
1293 {
1294 hddLog(VOS_TRACE_LEVEL_ERROR,
1295 FL("put_wifi_iface_stats fail") );
1296 kfree_skb(vendor_event);
1297 return;
1298 }
1299
Sunil Duttc69bccb2014-05-26 21:30:20 +05301300 hddLog(VOS_TRACE_LEVEL_INFO,
1301 "WMI_LINK_STATS_IFACE Data");
1302
1303 hddLog(VOS_TRACE_LEVEL_INFO,
1304 "LL_STATS_IFACE: "
1305 " Mode %u "
1306 " MAC %pM "
1307 " State %u "
1308 " Roaming %u "
1309 " capabilities 0x%x "
1310 " SSID %s "
1311 " BSSID %pM",
1312 pWifiIfaceStat->info.mode,
1313 pWifiIfaceStat->info.macAddr,
1314 pWifiIfaceStat->info.state,
1315 pWifiIfaceStat->info.roaming,
1316 pWifiIfaceStat->info.capabilities,
1317 pWifiIfaceStat->info.ssid,
1318 pWifiIfaceStat->info.bssid);
1319
1320 hddLog(VOS_TRACE_LEVEL_INFO,
1321 " AP country str: %c%c%c",
1322 pWifiIfaceStat->info.apCountryStr[0],
1323 pWifiIfaceStat->info.apCountryStr[1],
1324 pWifiIfaceStat->info.apCountryStr[2]);
1325
1326
1327 hddLog(VOS_TRACE_LEVEL_INFO,
1328 " Country Str Association: %c%c%c",
1329 pWifiIfaceStat->info.countryStr[0],
1330 pWifiIfaceStat->info.countryStr[1],
1331 pWifiIfaceStat->info.countryStr[2]);
1332
1333 hddLog(VOS_TRACE_LEVEL_INFO,
1334 " beaconRx %u "
1335 " mgmtRx %u "
1336 " mgmtActionRx %u "
1337 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301338 " rssiMgmt %d "
1339 " rssiData %d "
1340 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301341 pWifiIfaceStat->beaconRx,
1342 pWifiIfaceStat->mgmtRx,
1343 pWifiIfaceStat->mgmtActionRx,
1344 pWifiIfaceStat->mgmtActionTx,
1345 pWifiIfaceStat->rssiMgmt,
1346 pWifiIfaceStat->rssiData,
1347 pWifiIfaceStat->rssiAck );
1348
1349
1350 {
1351 int i;
1352 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1353 {
1354 hddLog(VOS_TRACE_LEVEL_INFO,
1355
1356 " %d) LL_STATS IFACE: "
1357 " ac: %u txMpdu: %u "
1358 " rxMpdu: %u txMcast: %u "
1359 " rxMcast: %u rxAmpdu: %u "
1360 " txAmpdu: %u mpduLost: %u "
1361 " retries: %u retriesShort: %u "
1362 " retriesLong: %u contentionTimeMin: %u "
1363 " contentionTimeMax: %u contentionTimeAvg: %u "
1364 " contentionNumSamples: %u",
1365 i,
1366 pWifiIfaceStat->AccessclassStats[i].ac,
1367 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1368 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1369 pWifiIfaceStat->AccessclassStats[i].txMcast,
1370 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1371 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1372 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1373 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1374 pWifiIfaceStat->AccessclassStats[i].retries,
1375 pWifiIfaceStat->
1376 AccessclassStats[i].retriesShort,
1377 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1378 pWifiIfaceStat->
1379 AccessclassStats[i].contentionTimeMin,
1380 pWifiIfaceStat->
1381 AccessclassStats[i].contentionTimeMax,
1382 pWifiIfaceStat->
1383 AccessclassStats[i].contentionTimeAvg,
1384 pWifiIfaceStat->
1385 AccessclassStats[i].contentionNumSamples);
1386
1387 }
1388 }
1389
Sunil Duttc69bccb2014-05-26 21:30:20 +05301390 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301391
1392 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301393}
1394
1395/*
1396 * hdd_link_layer_process_radio_stats () - This function is called after
1397 * receiving Link Layer Radio statistics from FW.This function converts
1398 * the firmware data to the NL data and sends the same to the kernel/upper
1399 * layers.
1400 */
1401static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1402 v_VOID_t *pData)
1403{
1404 int status, i;
1405 tpSirWifiRadioStat pWifiRadioStat;
1406 tpSirWifiChannelStats pWifiChannelStats;
1407 struct sk_buff *vendor_event;
1408 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1409 struct nlattr *chList;
1410
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301411 ENTER();
1412
Sunil Duttc69bccb2014-05-26 21:30:20 +05301413 status = wlan_hdd_validate_context(pHddCtx);
1414 if (0 != status)
1415 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301416 return;
1417 }
1418 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1419
1420 hddLog(VOS_TRACE_LEVEL_INFO,
1421 "LL_STATS_RADIO"
1422 " radio is %d onTime is %u "
1423 " txTime is %u rxTime is %u "
1424 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301425 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301426 " onTimePnoScan is %u onTimeHs20 is %u "
1427 " numChannels is %u",
1428 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1429 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1430 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301431 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301432 pWifiRadioStat->onTimeRoamScan,
1433 pWifiRadioStat->onTimePnoScan,
1434 pWifiRadioStat->onTimeHs20,
1435 pWifiRadioStat->numChannels);
1436 /*
1437 * Allocate a size of 4096 for the Radio stats comprising
1438 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1439 * (tSirWifiChannelStats).Each channel data is put with an
1440 * NL attribute.The size of 4096 is considered assuming that
1441 * number of channels shall not exceed beyond 60 with the
1442 * sizeof (tSirWifiChannelStats) being 24 bytes.
1443 */
1444
1445 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1446 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1447 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1448 GFP_KERNEL);
1449
1450 if (!vendor_event)
1451 {
1452 hddLog(VOS_TRACE_LEVEL_ERROR,
1453 FL("cfg80211_vendor_event_alloc failed") );
1454 return;
1455 }
1456
1457 if (nla_put_u32(vendor_event,
1458 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1459 pWifiRadioStat->radio) ||
1460 nla_put_u32(vendor_event,
1461 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1462 pWifiRadioStat->onTime) ||
1463 nla_put_u32(vendor_event,
1464 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1465 pWifiRadioStat->txTime) ||
1466 nla_put_u32(vendor_event,
1467 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1468 pWifiRadioStat->rxTime) ||
1469 nla_put_u32(vendor_event,
1470 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1471 pWifiRadioStat->onTimeScan) ||
1472 nla_put_u32(vendor_event,
1473 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1474 pWifiRadioStat->onTimeNbd) ||
1475 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301476 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1477 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301478 nla_put_u32(vendor_event,
1479 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1480 pWifiRadioStat->onTimeRoamScan) ||
1481 nla_put_u32(vendor_event,
1482 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1483 pWifiRadioStat->onTimePnoScan) ||
1484 nla_put_u32(vendor_event,
1485 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1486 pWifiRadioStat->onTimeHs20) ||
1487 nla_put_u32(vendor_event,
1488 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1489 pWifiRadioStat->numChannels))
1490 {
1491 hddLog(VOS_TRACE_LEVEL_ERROR,
1492 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1493 kfree_skb(vendor_event);
1494 return ;
1495 }
1496
1497 chList = nla_nest_start(vendor_event,
1498 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301499 if(!chList)
1500 {
1501 hddLog(VOS_TRACE_LEVEL_ERROR,
1502 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1503 __func__);
1504 kfree_skb(vendor_event);
1505 return;
1506 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301507 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1508 {
1509 struct nlattr *chInfo;
1510
1511 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1512 pWifiRadioStat->channels +
1513 (i * sizeof(tSirWifiChannelStats)));
1514
1515 hddLog(VOS_TRACE_LEVEL_INFO,
1516 " %d) Channel Info"
1517 " width is %u "
1518 " CenterFreq %u "
1519 " CenterFreq0 %u "
1520 " CenterFreq1 %u "
1521 " onTime %u "
1522 " ccaBusyTime %u",
1523 i,
1524 pWifiChannelStats->channel.width,
1525 pWifiChannelStats->channel.centerFreq,
1526 pWifiChannelStats->channel.centerFreq0,
1527 pWifiChannelStats->channel.centerFreq1,
1528 pWifiChannelStats->onTime,
1529 pWifiChannelStats->ccaBusyTime);
1530
1531
1532 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301533 if(!chInfo)
1534 {
1535 hddLog(VOS_TRACE_LEVEL_ERROR,
1536 "%s: failed to put chInfo",
1537 __func__);
1538 kfree_skb(vendor_event);
1539 return;
1540 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301541
1542 if (nla_put_u32(vendor_event,
1543 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1544 pWifiChannelStats->channel.width) ||
1545 nla_put_u32(vendor_event,
1546 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1547 pWifiChannelStats->channel.centerFreq) ||
1548 nla_put_u32(vendor_event,
1549 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1550 pWifiChannelStats->channel.centerFreq0) ||
1551 nla_put_u32(vendor_event,
1552 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1553 pWifiChannelStats->channel.centerFreq1) ||
1554 nla_put_u32(vendor_event,
1555 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1556 pWifiChannelStats->onTime) ||
1557 nla_put_u32(vendor_event,
1558 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1559 pWifiChannelStats->ccaBusyTime))
1560 {
1561 hddLog(VOS_TRACE_LEVEL_ERROR,
1562 FL("cfg80211_vendor_event_alloc failed") );
1563 kfree_skb(vendor_event);
1564 return ;
1565 }
1566 nla_nest_end(vendor_event, chInfo);
1567 }
1568 nla_nest_end(vendor_event, chList);
1569
1570 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301571
1572 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301573 return;
1574}
1575
1576/*
1577 * hdd_link_layer_stats_ind_callback () - This function is called after
1578 * receiving Link Layer indications from FW.This callback converts the firmware
1579 * data to the NL data and send the same to the kernel/upper layers.
1580 */
1581static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1582 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301583 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301584{
Dino Mycled3d50022014-07-07 12:58:25 +05301585 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1586 hdd_adapter_t *pAdapter = NULL;
1587 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301588 int status;
1589
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301590 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301591
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301592 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301593 if (0 != status)
1594 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301595 return;
1596 }
1597
Dino Mycled3d50022014-07-07 12:58:25 +05301598 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1599 if (NULL == pAdapter)
1600 {
1601 hddLog(VOS_TRACE_LEVEL_ERROR,
1602 FL(" MAC address %pM does not exist with host"),
1603 macAddr);
1604 return;
1605 }
1606
Sunil Duttc69bccb2014-05-26 21:30:20 +05301607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301608 "%s: Interface: %s LLStats indType: %d", __func__,
1609 pAdapter->dev->name, indType);
1610
Sunil Duttc69bccb2014-05-26 21:30:20 +05301611 switch (indType)
1612 {
1613 case SIR_HAL_LL_STATS_RESULTS_RSP:
1614 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301615 hddLog(VOS_TRACE_LEVEL_INFO,
1616 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1617 hddLog(VOS_TRACE_LEVEL_INFO,
1618 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1619 linkLayerStatsResults->paramId);
1620 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301621 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1622 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301623 hddLog(VOS_TRACE_LEVEL_INFO,
1624 "LL_STATS RESULTS RESPONSE respId = %u",
1625 linkLayerStatsResults->respId);
1626 hddLog(VOS_TRACE_LEVEL_INFO,
1627 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1628 linkLayerStatsResults->moreResultToFollow);
1629 hddLog(VOS_TRACE_LEVEL_INFO,
1630 "LL_STATS RESULTS RESPONSE result = %p",
1631 linkLayerStatsResults->result);
1632 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1633 {
1634 hdd_link_layer_process_radio_stats(pAdapter,
1635 (v_VOID_t *)linkLayerStatsResults->result);
1636 }
1637 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1638 {
1639 hdd_link_layer_process_iface_stats(pAdapter,
1640 (v_VOID_t *)linkLayerStatsResults->result);
1641 }
1642 else if ( linkLayerStatsResults->paramId &
1643 WMI_LINK_STATS_ALL_PEER )
1644 {
1645 hdd_link_layer_process_peer_stats(pAdapter,
1646 (v_VOID_t *)linkLayerStatsResults->result);
1647 } /* WMI_LINK_STATS_ALL_PEER */
1648 else
1649 {
1650 hddLog(VOS_TRACE_LEVEL_ERROR,
1651 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1652 }
1653
1654 break;
1655 }
1656 default:
1657 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1658 break;
1659 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301660
1661 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301662 return;
1663}
1664
1665const struct
1666nla_policy
1667qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1668{
1669 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1670 { .type = NLA_U32 },
1671 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1672 { .type = NLA_U32 },
1673};
1674
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301675static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1676 struct wireless_dev *wdev,
1677 const void *data,
1678 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301679{
1680 int status;
1681 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301682 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301683 struct net_device *dev = wdev->netdev;
1684 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1685 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Srinivas Dasari98947432014-11-07 19:41:24 +05301686 hdd_station_ctx_t *pHddStaCtx;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301687
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301688 ENTER();
1689
Sunil Duttc69bccb2014-05-26 21:30:20 +05301690 status = wlan_hdd_validate_context(pHddCtx);
1691 if (0 != status)
1692 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301693 return -EINVAL;
1694 }
1695
1696 if (NULL == pAdapter)
1697 {
1698 hddLog(VOS_TRACE_LEVEL_ERROR,
1699 FL("HDD adapter is Null"));
1700 return -ENODEV;
1701 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301702 /* check the LLStats Capability */
1703 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1704 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1705 {
1706 hddLog(VOS_TRACE_LEVEL_ERROR,
1707 FL("Link Layer Statistics not supported by Firmware"));
1708 return -EINVAL;
1709 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301710
1711 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1712 (struct nlattr *)data,
1713 data_len, qca_wlan_vendor_ll_set_policy))
1714 {
1715 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1716 return -EINVAL;
1717 }
1718 if (!tb_vendor
1719 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1720 {
1721 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1722 return -EINVAL;
1723 }
1724 if (!tb_vendor[
1725 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1726 {
1727 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1728 return -EINVAL;
1729 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301730 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301731 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301732
Dino Mycledf0a5d92014-07-04 09:41:55 +05301733 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301734 nla_get_u32(
1735 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1736
Dino Mycledf0a5d92014-07-04 09:41:55 +05301737 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301738 nla_get_u32(
1739 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1740
Dino Mycled3d50022014-07-07 12:58:25 +05301741 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1742 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301743
1744
1745 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301746 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301747 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301748 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301749 hddLog(VOS_TRACE_LEVEL_INFO,
1750 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301751 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301752 hddLog(VOS_TRACE_LEVEL_INFO,
1753 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301754 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301755
1756 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1757 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301758 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301759 {
1760 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1761 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301762 return -EINVAL;
1763
1764 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301765
1766 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1767 if (VOS_STATUS_SUCCESS !=
1768 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1769 pHddStaCtx->conn_info.staId[0], WIFI_STATS_IFACE))
1770 {
1771 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1772 "WLANTL_ClearInterfaceStats Failed", __func__);
1773 return -EINVAL;
1774 }
1775
1776 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
1777 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
1778 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
1779 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
1780
Sunil Duttc69bccb2014-05-26 21:30:20 +05301781 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301782 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301783 {
1784 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1785 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301786 return -EINVAL;
1787 }
1788
1789 pAdapter->isLinkLayerStatsSet = 1;
1790
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301791 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301792 return 0;
1793}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301794static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1795 struct wireless_dev *wdev,
1796 const void *data,
1797 int data_len)
1798{
1799 int ret = 0;
1800
1801 vos_ssr_protect(__func__);
1802 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1803 vos_ssr_unprotect(__func__);
1804
1805 return ret;
1806}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301807
1808const struct
1809nla_policy
1810qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1811{
1812 /* Unsigned 32bit value provided by the caller issuing the GET stats
1813 * command. When reporting
1814 * the stats results, the driver uses the same value to indicate
1815 * which GET request the results
1816 * correspond to.
1817 */
1818 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1819
1820 /* Unsigned 32bit value . bit mask to identify what statistics are
1821 requested for retrieval */
1822 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1823};
1824
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301825static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1826 struct wireless_dev *wdev,
1827 const void *data,
1828 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301829{
1830 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1831 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301832 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301833 struct net_device *dev = wdev->netdev;
1834 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1835 int status;
1836
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301837 ENTER();
1838
Sunil Duttc69bccb2014-05-26 21:30:20 +05301839 status = wlan_hdd_validate_context(pHddCtx);
1840 if (0 != status)
1841 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301842 return -EINVAL ;
1843 }
1844
1845 if (NULL == pAdapter)
1846 {
1847 hddLog(VOS_TRACE_LEVEL_FATAL,
1848 "%s: HDD adapter is Null", __func__);
1849 return -ENODEV;
1850 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301851 /* check the LLStats Capability */
1852 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1853 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1854 {
1855 hddLog(VOS_TRACE_LEVEL_ERROR,
1856 FL("Link Layer Statistics not supported by Firmware"));
1857 return -EINVAL;
1858 }
1859
Sunil Duttc69bccb2014-05-26 21:30:20 +05301860
1861 if (!pAdapter->isLinkLayerStatsSet)
1862 {
1863 hddLog(VOS_TRACE_LEVEL_FATAL,
1864 "%s: isLinkLayerStatsSet : %d",
1865 __func__, pAdapter->isLinkLayerStatsSet);
1866 return -EINVAL;
1867 }
1868
1869 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1870 (struct nlattr *)data,
1871 data_len, qca_wlan_vendor_ll_get_policy))
1872 {
1873 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1874 return -EINVAL;
1875 }
1876
1877 if (!tb_vendor
1878 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1879 {
1880 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1881 return -EINVAL;
1882 }
1883
1884 if (!tb_vendor
1885 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1886 {
1887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1888 return -EINVAL;
1889 }
1890
Sunil Duttc69bccb2014-05-26 21:30:20 +05301891
Dino Mycledf0a5d92014-07-04 09:41:55 +05301892 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301893 nla_get_u32( tb_vendor[
1894 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301895 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301896 nla_get_u32( tb_vendor[
1897 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1898
Dino Mycled3d50022014-07-07 12:58:25 +05301899 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1900 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301901
1902 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301903 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301904 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301905 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301906 hddLog(VOS_TRACE_LEVEL_INFO,
1907 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301908 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301909
1910 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301911 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301912 {
1913 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1914 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301915 return -EINVAL;
1916 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301917
1918 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301919 return 0;
1920}
1921
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301922static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1923 struct wireless_dev *wdev,
1924 const void *data,
1925 int data_len)
1926{
1927 int ret = 0;
1928
1929 vos_ssr_protect(__func__);
1930 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1931 vos_ssr_unprotect(__func__);
1932
1933 return ret;
1934}
1935
Sunil Duttc69bccb2014-05-26 21:30:20 +05301936const struct
1937nla_policy
1938qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1939{
1940 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1941 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1942 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1943 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1944};
1945
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301946static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1947 struct wireless_dev *wdev,
1948 const void *data,
1949 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301950{
1951 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1952 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301953 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301954 struct net_device *dev = wdev->netdev;
1955 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1956 u32 statsClearReqMask;
1957 u8 stopReq;
1958 int status;
1959
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301960 ENTER();
1961
Sunil Duttc69bccb2014-05-26 21:30:20 +05301962 status = wlan_hdd_validate_context(pHddCtx);
1963 if (0 != status)
1964 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301965 return -EINVAL;
1966 }
1967
1968 if (NULL == pAdapter)
1969 {
1970 hddLog(VOS_TRACE_LEVEL_FATAL,
1971 "%s: HDD adapter is Null", __func__);
1972 return -ENODEV;
1973 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301974 /* check the LLStats Capability */
1975 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1976 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1977 {
1978 hddLog(VOS_TRACE_LEVEL_ERROR,
1979 FL("Enable LLStats Capability"));
1980 return -EINVAL;
1981 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301982
1983 if (!pAdapter->isLinkLayerStatsSet)
1984 {
1985 hddLog(VOS_TRACE_LEVEL_FATAL,
1986 "%s: isLinkLayerStatsSet : %d",
1987 __func__, pAdapter->isLinkLayerStatsSet);
1988 return -EINVAL;
1989 }
1990
1991 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1992 (struct nlattr *)data,
1993 data_len, qca_wlan_vendor_ll_clr_policy))
1994 {
1995 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1996 return -EINVAL;
1997 }
1998
1999 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2000
2001 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2002 {
2003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2004 return -EINVAL;
2005
2006 }
2007
Sunil Duttc69bccb2014-05-26 21:30:20 +05302008
Dino Mycledf0a5d92014-07-04 09:41:55 +05302009 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302010 nla_get_u32(
2011 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2012
Dino Mycledf0a5d92014-07-04 09:41:55 +05302013 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302014 nla_get_u8(
2015 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2016
2017 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302018 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302019
Dino Mycled3d50022014-07-07 12:58:25 +05302020 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2021 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302022
2023 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302024 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302025 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302026 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302027 hddLog(VOS_TRACE_LEVEL_INFO,
2028 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302029 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302030 hddLog(VOS_TRACE_LEVEL_INFO,
2031 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302032 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302033
2034 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302035 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302036 {
2037 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302038 hdd_station_ctx_t *pHddStaCtx;
2039
2040 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2041 if (VOS_STATUS_SUCCESS !=
2042 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2043 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2044 {
2045 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2046 "WLANTL_ClearInterfaceStats Failed", __func__);
2047 return -EINVAL;
2048 }
2049 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2050 (statsClearReqMask & WIFI_STATS_IFACE)) {
2051 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2052 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2053 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2054 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2055 }
2056
Sunil Duttc69bccb2014-05-26 21:30:20 +05302057 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2058 2 * sizeof(u32) +
2059 NLMSG_HDRLEN);
2060
2061 if (temp_skbuff != NULL)
2062 {
2063
2064 if (nla_put_u32(temp_skbuff,
2065 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2066 statsClearReqMask) ||
2067 nla_put_u32(temp_skbuff,
2068 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2069 stopReq))
2070 {
2071 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2072 kfree_skb(temp_skbuff);
2073 return -EINVAL;
2074 }
2075 /* If the ask is to stop the stats collection as part of clear
2076 * (stopReq = 1) , ensure that no further requests of get
2077 * go to the firmware by having isLinkLayerStatsSet set to 0.
2078 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302079 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302080 * case the firmware is just asked to clear the statistics.
2081 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302082 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302083 pAdapter->isLinkLayerStatsSet = 0;
2084 return cfg80211_vendor_cmd_reply(temp_skbuff);
2085 }
2086 return -ENOMEM;
2087 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302088
2089 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302090 return -EINVAL;
2091}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302092static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2093 struct wireless_dev *wdev,
2094 const void *data,
2095 int data_len)
2096{
2097 int ret = 0;
2098
2099 vos_ssr_protect(__func__);
2100 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2101 vos_ssr_unprotect(__func__);
2102
2103 return ret;
2104
2105
2106}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302107#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2108
Dino Mycle6fb96c12014-06-10 11:52:40 +05302109#ifdef WLAN_FEATURE_EXTSCAN
2110static const struct nla_policy
2111wlan_hdd_extscan_config_policy
2112 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2113{
2114 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2115 { .type = NLA_U32 },
2116 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2117 { .type = NLA_U32 },
2118 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2119 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2120 { .type = NLA_U32 },
2121 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2122 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2123
2124 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2125 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2126 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2127 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2128 { .type = NLA_U8 },
2129 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2130 { .type = NLA_U32 },
2131 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2132 { .type = NLA_U32 },
2133 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2134 { .type = NLA_U32 },
2135 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
2136 { .type = NLA_U8 },
2137 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2138 { .type = NLA_U8 },
2139 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2140 { .type = NLA_U8 },
2141
2142 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2143 { .type = NLA_U32 },
2144 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2145 { .type = NLA_UNSPEC },
2146 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2147 { .type = NLA_S32 },
2148 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2149 { .type = NLA_S32 },
2150 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2151 { .type = NLA_U32 },
2152 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2153 { .type = NLA_U32 },
2154 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2155 { .type = NLA_U32 },
2156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2157 = { .type = NLA_U32 },
2158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2159 { .type = NLA_U32 },
2160 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2161 NLA_U32 },
2162};
2163
2164static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2165{
2166 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2167 struct sk_buff *skb = NULL;
2168 tpSirEXTScanCapabilitiesEvent pData =
2169 (tpSirEXTScanCapabilitiesEvent) pMsg;
2170
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302171 ENTER();
2172
2173 if (wlan_hdd_validate_context(pHddCtx))
2174 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302175 return;
2176 }
2177
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302178 if (!pMsg)
2179 {
2180 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2181 return;
2182 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302183 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2184 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2185 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2186 GFP_KERNEL);
2187
2188 if (!skb) {
2189 hddLog(VOS_TRACE_LEVEL_ERROR,
2190 FL("cfg80211_vendor_event_alloc failed"));
2191 return;
2192 }
2193
2194 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2195 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2196 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2197 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2198 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2199 pData->maxRssiSampleSize);
2200 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2201 pData->maxScanReportingThreshold);
2202 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2203 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2204 pData->maxSignificantWifiChangeAPs);
2205 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2206 pData->maxBsidHistoryEntries);
2207
2208 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2209 pData->requestId) ||
2210 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2211 nla_put_u32(skb,
2212 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2213 pData->scanCacheSize) ||
2214 nla_put_u32(skb,
2215 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2216 pData->scanBuckets) ||
2217 nla_put_u32(skb,
2218 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2219 pData->maxApPerScan) ||
2220 nla_put_u32(skb,
2221 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2222 pData->maxRssiSampleSize) ||
2223 nla_put_u32(skb,
2224 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2225 pData->maxScanReportingThreshold) ||
2226 nla_put_u32(skb,
2227 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2228 pData->maxHotlistAPs) ||
2229 nla_put_u32(skb,
2230 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2231 pData->maxSignificantWifiChangeAPs) ||
2232 nla_put_u32(skb,
2233 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2234 pData->maxBsidHistoryEntries)) {
2235 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2236 goto nla_put_failure;
2237 }
2238
2239 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302240 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302241 return;
2242
2243nla_put_failure:
2244 kfree_skb(skb);
2245 return;
2246}
2247
2248
2249static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2250{
2251 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2252 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2253 struct sk_buff *skb = NULL;
2254 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2255
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302256 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302257
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302258 if (wlan_hdd_validate_context(pHddCtx)){
2259 return;
2260 }
2261 if (!pMsg)
2262 {
2263 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302264 return;
2265 }
2266
2267 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2268 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2269 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2270 GFP_KERNEL);
2271
2272 if (!skb) {
2273 hddLog(VOS_TRACE_LEVEL_ERROR,
2274 FL("cfg80211_vendor_event_alloc failed"));
2275 return;
2276 }
2277 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2278 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2279 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2280
2281 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2282 pData->requestId) ||
2283 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2284 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2285 goto nla_put_failure;
2286 }
2287
2288 /*
2289 * Store the Request ID for comparing with the requestID obtained
2290 * in other requests.HDD shall return a failure is the extscan_stop
2291 * request is issued with a different requestId as that of the
2292 * extscan_start request. Also, This requestId shall be used while
2293 * indicating the full scan results to the upper layers.
2294 * The requestId is stored with the assumption that the firmware
2295 * shall return the ext scan start request's requestId in ext scan
2296 * start response.
2297 */
2298 if (pData->status == 0)
2299 pMac->sme.extScanStartReqId = pData->requestId;
2300
2301
2302 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302303 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302304 return;
2305
2306nla_put_failure:
2307 kfree_skb(skb);
2308 return;
2309}
2310
2311
2312static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2313{
2314 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2315 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2316 struct sk_buff *skb = NULL;
2317
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302318 ENTER();
2319
2320 if (wlan_hdd_validate_context(pHddCtx)){
2321 return;
2322 }
2323 if (!pMsg)
2324 {
2325 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302326 return;
2327 }
2328
2329 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2330 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2331 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2332 GFP_KERNEL);
2333
2334 if (!skb) {
2335 hddLog(VOS_TRACE_LEVEL_ERROR,
2336 FL("cfg80211_vendor_event_alloc failed"));
2337 return;
2338 }
2339 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2340 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2341
2342 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2343 pData->requestId) ||
2344 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2346 goto nla_put_failure;
2347 }
2348
2349 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302350 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302351 return;
2352
2353nla_put_failure:
2354 kfree_skb(skb);
2355 return;
2356}
2357
2358
2359static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2360 void *pMsg)
2361{
2362 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2363 struct sk_buff *skb = NULL;
2364 tpSirEXTScanSetBssidHotListRspParams pData =
2365 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2366
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302367 ENTER();
2368
2369 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302370 return;
2371 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302372 if (!pMsg)
2373 {
2374 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2375 return;
2376 }
2377
Dino Mycle6fb96c12014-06-10 11:52:40 +05302378 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2379 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2380 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2381 GFP_KERNEL);
2382
2383 if (!skb) {
2384 hddLog(VOS_TRACE_LEVEL_ERROR,
2385 FL("cfg80211_vendor_event_alloc failed"));
2386 return;
2387 }
2388 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2389 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2390 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2391
2392 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2393 pData->requestId) ||
2394 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2396 goto nla_put_failure;
2397 }
2398
2399 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302400 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302401 return;
2402
2403nla_put_failure:
2404 kfree_skb(skb);
2405 return;
2406}
2407
2408static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2409 void *pMsg)
2410{
2411 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2412 struct sk_buff *skb = NULL;
2413 tpSirEXTScanResetBssidHotlistRspParams pData =
2414 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2415
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302416 ENTER();
2417
2418 if (wlan_hdd_validate_context(pHddCtx)) {
2419 return;
2420 }
2421 if (!pMsg)
2422 {
2423 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302424 return;
2425 }
2426
2427 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2428 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2429 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2430 GFP_KERNEL);
2431
2432 if (!skb) {
2433 hddLog(VOS_TRACE_LEVEL_ERROR,
2434 FL("cfg80211_vendor_event_alloc failed"));
2435 return;
2436 }
2437 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2438 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2439
2440 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2441 pData->requestId) ||
2442 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2443 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2444 goto nla_put_failure;
2445 }
2446
2447 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302448 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302449 return;
2450
2451nla_put_failure:
2452 kfree_skb(skb);
2453 return;
2454}
2455
2456
2457static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2458 void *pMsg)
2459{
2460 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2461 struct sk_buff *skb = NULL;
2462 tpSirEXTScanSetSignificantChangeRspParams pData =
2463 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2464
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302465 ENTER();
2466
2467 if (wlan_hdd_validate_context(pHddCtx)) {
2468 return;
2469 }
2470 if (!pMsg)
2471 {
2472 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302473 return;
2474 }
2475
2476 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2477 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2478 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2479 GFP_KERNEL);
2480
2481 if (!skb) {
2482 hddLog(VOS_TRACE_LEVEL_ERROR,
2483 FL("cfg80211_vendor_event_alloc failed"));
2484 return;
2485 }
2486 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2487 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2488 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2489
2490 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2491 pData->requestId) ||
2492 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2493 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2494 goto nla_put_failure;
2495 }
2496
2497 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302498 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302499 return;
2500
2501nla_put_failure:
2502 kfree_skb(skb);
2503 return;
2504}
2505
2506
2507static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2508 void *pMsg)
2509{
2510 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2511 struct sk_buff *skb = NULL;
2512 tpSirEXTScanResetSignificantChangeRspParams pData =
2513 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2514
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302515 ENTER();
2516
2517 if (wlan_hdd_validate_context(pHddCtx)) {
2518 return;
2519 }
2520 if (!pMsg)
2521 {
2522 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302523 return;
2524 }
2525
2526 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2527 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2528 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2529 GFP_KERNEL);
2530
2531 if (!skb) {
2532 hddLog(VOS_TRACE_LEVEL_ERROR,
2533 FL("cfg80211_vendor_event_alloc failed"));
2534 return;
2535 }
2536 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2537 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2538 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2539
2540 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2541 pData->requestId) ||
2542 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2543 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2544 goto nla_put_failure;
2545 }
2546
2547 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302548 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302549 return;
2550
2551nla_put_failure:
2552 kfree_skb(skb);
2553 return;
2554}
2555
2556static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2557 void *pMsg)
2558{
2559 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2560 struct sk_buff *skb = NULL;
2561 tANI_U32 i = 0, j, resultsPerEvent;
2562 tANI_S32 totalResults;
2563 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2564 tpSirWifiScanResult pSirWifiScanResult;
2565
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302566 ENTER();
2567
2568 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302569 return;
2570 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302571 if (!pMsg)
2572 {
2573 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2574 return;
2575 }
2576
Dino Mycle6fb96c12014-06-10 11:52:40 +05302577 totalResults = pData->numOfAps;
2578 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2579 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2580 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2581
2582 do{
2583 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2584 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2585 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2586
2587 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2588 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2589 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2590 GFP_KERNEL);
2591
2592 if (!skb) {
2593 hddLog(VOS_TRACE_LEVEL_ERROR,
2594 FL("cfg80211_vendor_event_alloc failed"));
2595 return;
2596 }
2597
2598 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2599
2600 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2601 pData->requestId) ||
2602 nla_put_u32(skb,
2603 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2604 resultsPerEvent)) {
2605 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2606 goto fail;
2607 }
2608 if (nla_put_u8(skb,
2609 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2610 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2611 {
2612 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2613 goto fail;
2614 }
2615
2616 if (resultsPerEvent) {
2617 struct nlattr *aps;
2618
2619 aps = nla_nest_start(skb,
2620 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2621 if (!aps)
2622 {
2623 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2624 goto fail;
2625 }
2626
2627 for (j = 0; j < resultsPerEvent; j++, i++) {
2628 struct nlattr *ap;
2629 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2630 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2631
2632 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2633 "Ssid (%s)"
2634 "Bssid: %pM "
2635 "Channel (%u)"
2636 "Rssi (%d)"
2637 "RTT (%u)"
2638 "RTT_SD (%u)",
2639 i,
2640 pSirWifiScanResult->ts,
2641 pSirWifiScanResult->ssid,
2642 pSirWifiScanResult->bssid,
2643 pSirWifiScanResult->channel,
2644 pSirWifiScanResult->rssi,
2645 pSirWifiScanResult->rtt,
2646 pSirWifiScanResult->rtt_sd);
2647
2648 ap = nla_nest_start(skb, j + 1);
2649 if (!ap)
2650 {
2651 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2652 goto fail;
2653 }
2654
2655 if (nla_put_u64(skb,
2656 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2657 pSirWifiScanResult->ts) )
2658 {
2659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2660 goto fail;
2661 }
2662 if (nla_put(skb,
2663 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2664 sizeof(pSirWifiScanResult->ssid),
2665 pSirWifiScanResult->ssid) )
2666 {
2667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2668 goto fail;
2669 }
2670 if (nla_put(skb,
2671 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2672 sizeof(pSirWifiScanResult->bssid),
2673 pSirWifiScanResult->bssid) )
2674 {
2675 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2676 goto fail;
2677 }
2678 if (nla_put_u32(skb,
2679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2680 pSirWifiScanResult->channel) )
2681 {
2682 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2683 goto fail;
2684 }
Dasari Srinivas90747d72014-10-08 12:16:15 +05302685 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302686 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2687 pSirWifiScanResult->rssi) )
2688 {
2689 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2690 goto fail;
2691 }
2692 if (nla_put_u32(skb,
2693 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2694 pSirWifiScanResult->rtt) )
2695 {
2696 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2697 goto fail;
2698 }
2699 if (nla_put_u32(skb,
2700 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2701 pSirWifiScanResult->rtt_sd))
2702 {
2703 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2704 goto fail;
2705 }
2706
2707 nla_nest_end(skb, ap);
2708 }
2709 nla_nest_end(skb, aps);
2710
2711 }
2712 cfg80211_vendor_event(skb, GFP_KERNEL);
2713 } while (totalResults > 0);
2714
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302715 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302716 return;
2717fail:
2718 kfree_skb(skb);
2719 return;
2720}
2721
2722static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2723 void *pMsg)
2724{
2725 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2726 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2727 struct sk_buff *skb = NULL;
2728 tANI_U32 i;
2729
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302730 ENTER();
2731
2732 if (wlan_hdd_validate_context(pHddCtx)) {
2733 return;
2734 }
2735 if (!pMsg)
2736 {
2737 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302738 return;
2739 }
2740
2741 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2742 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2743 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2744 GFP_KERNEL);
2745
2746 if (!skb) {
2747 hddLog(VOS_TRACE_LEVEL_ERROR,
2748 FL("cfg80211_vendor_event_alloc failed"));
2749 return;
2750 }
2751 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2752 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2753 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2754 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2755
2756 for (i = 0; i < pData->numOfAps; i++) {
2757 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2758 "Ssid (%s) "
2759 "Bssid (" MAC_ADDRESS_STR ") "
2760 "Channel (%u) "
2761 "Rssi (%d) "
2762 "RTT (%u) "
2763 "RTT_SD (%u) ",
2764 i,
2765 pData->ap[i].ts,
2766 pData->ap[i].ssid,
2767 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2768 pData->ap[i].channel,
2769 pData->ap[i].rssi,
2770 pData->ap[i].rtt,
2771 pData->ap[i].rtt_sd);
2772 }
2773
2774 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2775 pData->requestId) ||
2776 nla_put_u32(skb,
2777 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2778 pData->numOfAps)) {
2779 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2780 goto fail;
2781 }
2782 if (pData->numOfAps) {
2783 struct nlattr *aps;
2784
2785 aps = nla_nest_start(skb,
2786 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2787 if (!aps)
2788 goto fail;
2789
2790 for (i = 0; i < pData->numOfAps; i++) {
2791 struct nlattr *ap;
2792
2793 ap = nla_nest_start(skb, i + 1);
2794 if (!ap)
2795 goto fail;
2796
2797 if (nla_put_u64(skb,
2798 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2799 pData->ap[i].ts) ||
2800 nla_put(skb,
2801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2802 sizeof(pData->ap[i].ssid),
2803 pData->ap[i].ssid) ||
2804 nla_put(skb,
2805 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2806 sizeof(pData->ap[i].bssid),
2807 pData->ap[i].bssid) ||
2808 nla_put_u32(skb,
2809 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2810 pData->ap[i].channel) ||
2811 nla_put_s32(skb,
2812 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2813 pData->ap[i].rssi) ||
2814 nla_put_u32(skb,
2815 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2816 pData->ap[i].rtt) ||
2817 nla_put_u32(skb,
2818 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2819 pData->ap[i].rtt_sd))
2820 goto fail;
2821
2822 nla_nest_end(skb, ap);
2823 }
2824 nla_nest_end(skb, aps);
2825
2826 if (nla_put_u8(skb,
2827 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2828 pData->moreData))
2829 goto fail;
2830 }
2831
2832 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302833 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302834 return;
2835
2836fail:
2837 kfree_skb(skb);
2838 return;
2839
2840}
2841static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2842 void *pMsg)
2843{
2844 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2845 struct sk_buff *skb = NULL;
2846 tANI_U32 i, j;
2847 tpSirWifiSignificantChangeEvent pData =
2848 (tpSirWifiSignificantChangeEvent) pMsg;
2849
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302850 ENTER();
2851
2852 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302853 return;
2854 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302855 if (!pMsg)
2856 {
2857 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2858 return;
2859 }
2860
Dino Mycle6fb96c12014-06-10 11:52:40 +05302861 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2862 EXTSCAN_EVENT_BUF_SIZE,
2863 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2864 GFP_KERNEL);
2865
2866 if (!skb) {
2867 hddLog(VOS_TRACE_LEVEL_ERROR,
2868 FL("cfg80211_vendor_event_alloc failed"));
2869 return;
2870 }
2871 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2872 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2873 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2874 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2875 pData->numSigRssiBss);
2876 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2877
2878 for (i = 0; i < pData->numSigRssiBss; i++) {
2879 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2880 " num RSSI %u ",
2881 i, pData->sigRssiResult[i].bssid,
2882 pData->sigRssiResult[i].channel,
2883 pData->sigRssiResult[i].numRssi);
2884
2885 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2886
2887 hddLog(VOS_TRACE_LEVEL_INFO,
2888 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05302889 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302890
2891 }
2892 }
2893
2894
2895 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2896 pData->requestId) ||
2897 nla_put_u32(skb,
2898 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2899 pData->numSigRssiBss)) {
2900 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2901 goto fail;
2902 }
2903
2904 if (pData->numSigRssiBss) {
2905 struct nlattr *aps;
2906 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2907 if (!aps)
2908 goto fail;
2909 for (i = 0; i < pData->numSigRssiBss; i++) {
2910 struct nlattr *ap;
2911
2912 ap = nla_nest_start(skb, i);
2913 if (!ap)
2914 goto fail;
2915 if (nla_put(skb,
2916 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2917 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2918 nla_put_u32(skb,
2919 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2920 pData->sigRssiResult[i].channel) ||
2921 nla_put_u32(skb,
2922 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2923 pData->sigRssiResult[i].numRssi) ||
2924 nla_put(skb,
2925 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2926 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2927 pData->sigRssiResult[i].rssi))
2928 goto fail;
2929 nla_nest_end(skb, ap);
2930 }
2931 nla_nest_end(skb, aps);
2932 if (nla_put_u8(skb,
2933 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2934 pData->moreData))
2935 goto fail;
2936 }
2937 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302938 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302939 return;
2940fail:
2941 kfree_skb(skb);
2942 return;
2943}
2944
2945static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2946 void *pMsg)
2947{
2948 struct sk_buff *skb;
2949 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2950 tpSirWifiFullScanResultEvent pData =
2951 (tpSirWifiFullScanResultEvent) (pMsg);
2952
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302953 ENTER();
2954
2955 if (wlan_hdd_validate_context(pHddCtx)) {
2956 return;
2957 }
2958 if (!pMsg)
2959 {
2960 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302961 return;
2962 }
2963
2964 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2965 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2966 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2967 GFP_KERNEL);
2968
2969 if (!skb) {
2970 hddLog(VOS_TRACE_LEVEL_ERROR,
2971 FL("cfg80211_vendor_event_alloc failed"));
2972 return;
2973 }
2974
2975 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2976 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2977 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2978 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2979 "Ssid (%s)"
2980 "Bssid (" MAC_ADDRESS_STR ")"
2981 "Channel (%u)"
2982 "Rssi (%d)"
2983 "RTT (%u)"
2984 "RTT_SD (%u)"),
2985 pData->ap.ts,
2986 pData->ap.ssid,
2987 MAC_ADDR_ARRAY(pData->ap.bssid),
2988 pData->ap.channel,
2989 pData->ap.rssi,
2990 pData->ap.rtt,
2991 pData->ap.rtt_sd);
2992 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2993 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2994 pData->requestId) ||
2995 nla_put_u64(skb,
2996 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2997 pData->ap.ts) ||
2998 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2999 sizeof(pData->ap.ssid),
3000 pData->ap.ssid) ||
3001 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3002 WNI_CFG_BSSID_LEN,
3003 pData->ap.bssid) ||
3004 nla_put_u32(skb,
3005 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3006 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303007 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303008 pData->ap.rssi) ||
3009 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3010 pData->ap.rtt) ||
3011 nla_put_u32(skb,
3012 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3013 pData->ap.rtt_sd) ||
3014 nla_put_u16(skb,
3015 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3016 pData->ap.beaconPeriod) ||
3017 nla_put_u16(skb,
3018 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3019 pData->ap.capability) ||
3020 nla_put_u32(skb,
3021 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3022 pData->ieLength))
3023 {
3024 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3025 goto nla_put_failure;
3026 }
3027 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3028 pData->ieLength,
3029 pData->ie))
3030 {
3031 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3032 goto nla_put_failure;
3033 }
3034
3035 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303036 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303037 return;
3038
3039nla_put_failure:
3040 kfree_skb(skb);
3041 return;
3042}
3043
3044static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3045 void *pMsg)
3046{
3047 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3048 struct sk_buff *skb = NULL;
3049 tpSirEXTScanResultsAvailableIndParams pData =
3050 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3051
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303052 ENTER();
3053
3054 if (wlan_hdd_validate_context(pHddCtx)){
3055 return;
3056 }
3057 if (!pMsg)
3058 {
3059 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303060 return;
3061 }
3062
3063 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
3064 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3065 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3066 GFP_KERNEL);
3067
3068 if (!skb) {
3069 hddLog(VOS_TRACE_LEVEL_ERROR,
3070 FL("cfg80211_vendor_event_alloc failed"));
3071 return;
3072 }
3073
3074 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3075 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3076 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3077 pData->numResultsAvailable);
3078 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3079 pData->requestId) ||
3080 nla_put_u32(skb,
3081 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3082 pData->numResultsAvailable)) {
3083 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3084 goto nla_put_failure;
3085 }
3086
3087 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303088 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303089 return;
3090
3091nla_put_failure:
3092 kfree_skb(skb);
3093 return;
3094}
3095
3096static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3097{
3098 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3099 struct sk_buff *skb = NULL;
3100 tpSirEXTScanProgressIndParams pData =
3101 (tpSirEXTScanProgressIndParams) pMsg;
3102
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303103 ENTER();
3104
3105 if (wlan_hdd_validate_context(pHddCtx)){
3106 return;
3107 }
3108 if (!pMsg)
3109 {
3110 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303111 return;
3112 }
3113
3114 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
3115 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3116 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3117 GFP_KERNEL);
3118
3119 if (!skb) {
3120 hddLog(VOS_TRACE_LEVEL_ERROR,
3121 FL("cfg80211_vendor_event_alloc failed"));
3122 return;
3123 }
3124 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3125 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3126 pData->extScanEventType);
3127 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3128 pData->status);
3129
3130 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3131 pData->extScanEventType) ||
3132 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303133 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3134 pData->requestId) ||
3135 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303136 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3137 pData->status)) {
3138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3139 goto nla_put_failure;
3140 }
3141
3142 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303143 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303144 return;
3145
3146nla_put_failure:
3147 kfree_skb(skb);
3148 return;
3149}
3150
3151void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3152 void *pMsg)
3153{
3154 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3155
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303156 ENTER();
3157
Dino Mycle6fb96c12014-06-10 11:52:40 +05303158 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303159 return;
3160 }
3161
3162 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3163
3164
3165 switch(evType) {
3166 case SIR_HAL_EXTSCAN_START_RSP:
3167 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3168 break;
3169
3170 case SIR_HAL_EXTSCAN_STOP_RSP:
3171 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3172 break;
3173 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3174 /* There is no need to send this response to upper layer
3175 Just log the message */
3176 hddLog(VOS_TRACE_LEVEL_INFO,
3177 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3178 break;
3179 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3180 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3181 break;
3182
3183 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3184 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3185 break;
3186
3187 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
3188 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
3189 break;
3190
3191 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
3192 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
3193 break;
3194 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
3195 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
3196 break;
3197 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3198 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3199 break;
3200 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3201 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3202 break;
3203 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3204 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3205 break;
3206 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3207 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3208 break;
3209 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
3210 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
3211 break;
3212 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3213 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3214 break;
3215 default:
3216 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3217 break;
3218 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303219 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303220}
3221
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303222static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3223 struct wireless_dev *wdev,
3224 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303225{
Dino Myclee8843b32014-07-04 14:21:45 +05303226 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303227 struct net_device *dev = wdev->netdev;
3228 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3229 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3230 struct nlattr
3231 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3232 eHalStatus status;
3233
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303234 ENTER();
3235
Dino Mycle6fb96c12014-06-10 11:52:40 +05303236 status = wlan_hdd_validate_context(pHddCtx);
3237 if (0 != status)
3238 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303239 return -EINVAL;
3240 }
Dino Myclee8843b32014-07-04 14:21:45 +05303241 /* check the EXTScan Capability */
3242 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3243 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3244 {
3245 hddLog(VOS_TRACE_LEVEL_ERROR,
3246 FL("EXTScan not enabled/supported by Firmware"));
3247 return -EINVAL;
3248 }
3249
Dino Mycle6fb96c12014-06-10 11:52:40 +05303250 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3251 data, dataLen,
3252 wlan_hdd_extscan_config_policy)) {
3253 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3254 return -EINVAL;
3255 }
3256
3257 /* Parse and fetch request Id */
3258 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3259 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3260 return -EINVAL;
3261 }
3262
Dino Mycle6fb96c12014-06-10 11:52:40 +05303263
Dino Myclee8843b32014-07-04 14:21:45 +05303264 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303265 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303266 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303267
Dino Myclee8843b32014-07-04 14:21:45 +05303268 reqMsg.sessionId = pAdapter->sessionId;
3269 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303270
Dino Myclee8843b32014-07-04 14:21:45 +05303271 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303272 if (!HAL_STATUS_SUCCESS(status)) {
3273 hddLog(VOS_TRACE_LEVEL_ERROR,
3274 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303275 return -EINVAL;
3276 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303277 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303278 return 0;
3279}
3280
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303281static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3282 struct wireless_dev *wdev,
3283 const void *data, int dataLen)
3284{
3285 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303286
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303287 vos_ssr_protect(__func__);
3288 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3289 vos_ssr_unprotect(__func__);
3290
3291 return ret;
3292}
3293
3294static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3295 struct wireless_dev *wdev,
3296 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303297{
Dino Myclee8843b32014-07-04 14:21:45 +05303298 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303299 struct net_device *dev = wdev->netdev;
3300 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3301 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3302 struct nlattr
3303 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3304 eHalStatus status;
3305
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303306 ENTER();
3307
Dino Mycle6fb96c12014-06-10 11:52:40 +05303308 status = wlan_hdd_validate_context(pHddCtx);
3309 if (0 != status)
3310 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303311 return -EINVAL;
3312 }
Dino Myclee8843b32014-07-04 14:21:45 +05303313 /* check the EXTScan Capability */
3314 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3315 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3316 {
3317 hddLog(VOS_TRACE_LEVEL_ERROR,
3318 FL("EXTScan not enabled/supported by Firmware"));
3319 return -EINVAL;
3320 }
3321
Dino Mycle6fb96c12014-06-10 11:52:40 +05303322 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3323 data, dataLen,
3324 wlan_hdd_extscan_config_policy)) {
3325 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3326 return -EINVAL;
3327 }
3328 /* Parse and fetch request Id */
3329 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3330 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3331 return -EINVAL;
3332 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303333
Dino Myclee8843b32014-07-04 14:21:45 +05303334 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303335 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3336
Dino Myclee8843b32014-07-04 14:21:45 +05303337 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303338
Dino Myclee8843b32014-07-04 14:21:45 +05303339 reqMsg.sessionId = pAdapter->sessionId;
3340 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303341
3342 /* Parse and fetch flush parameter */
3343 if (!tb
3344 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3345 {
3346 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3347 goto failed;
3348 }
Dino Myclee8843b32014-07-04 14:21:45 +05303349 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303350 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3351
Dino Myclee8843b32014-07-04 14:21:45 +05303352 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303353
Dino Myclee8843b32014-07-04 14:21:45 +05303354 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303355 if (!HAL_STATUS_SUCCESS(status)) {
3356 hddLog(VOS_TRACE_LEVEL_ERROR,
3357 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303358 return -EINVAL;
3359 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303360 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303361 return 0;
3362
3363failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303364 return -EINVAL;
3365}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303366static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3367 struct wireless_dev *wdev,
3368 const void *data, int dataLen)
3369{
3370 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303371
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303372 vos_ssr_protect(__func__);
3373 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3374 vos_ssr_unprotect(__func__);
3375
3376 return ret;
3377}
3378
3379static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303380 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303381 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303382{
3383 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3384 struct net_device *dev = wdev->netdev;
3385 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3386 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3387 struct nlattr
3388 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3389 struct nlattr
3390 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3391 struct nlattr *apTh;
3392 eHalStatus status;
3393 tANI_U8 i = 0;
3394 int rem;
3395
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303396 ENTER();
3397
Dino Mycle6fb96c12014-06-10 11:52:40 +05303398 status = wlan_hdd_validate_context(pHddCtx);
3399 if (0 != status)
3400 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303401 return -EINVAL;
3402 }
Dino Myclee8843b32014-07-04 14:21:45 +05303403 /* check the EXTScan Capability */
3404 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3405 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3406 {
3407 hddLog(VOS_TRACE_LEVEL_ERROR,
3408 FL("EXTScan not enabled/supported by Firmware"));
3409 return -EINVAL;
3410 }
3411
Dino Mycle6fb96c12014-06-10 11:52:40 +05303412 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3413 data, dataLen,
3414 wlan_hdd_extscan_config_policy)) {
3415 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3416 return -EINVAL;
3417 }
3418
3419 /* Parse and fetch request Id */
3420 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3421 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3422 return -EINVAL;
3423 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303424 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3425 vos_mem_malloc(sizeof(*pReqMsg));
3426 if (!pReqMsg) {
3427 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3428 return -ENOMEM;
3429 }
3430
Dino Myclee8843b32014-07-04 14:21:45 +05303431
Dino Mycle6fb96c12014-06-10 11:52:40 +05303432 pReqMsg->requestId = nla_get_u32(
3433 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3434 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3435
3436 /* Parse and fetch number of APs */
3437 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3438 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3439 goto fail;
3440 }
3441
3442 pReqMsg->sessionId = pAdapter->sessionId;
3443 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3444
3445 pReqMsg->numAp = nla_get_u32(
3446 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3447 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3448
3449 nla_for_each_nested(apTh,
3450 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3451 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3452 nla_data(apTh), nla_len(apTh),
3453 NULL)) {
3454 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3455 goto fail;
3456 }
3457
3458 /* Parse and fetch MAC address */
3459 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3460 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3461 goto fail;
3462 }
3463 memcpy(pReqMsg->ap[i].bssid, nla_data(
3464 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3465 sizeof(tSirMacAddr));
3466 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3467
3468 /* Parse and fetch low RSSI */
3469 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3470 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3471 goto fail;
3472 }
3473 pReqMsg->ap[i].low = nla_get_s32(
3474 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3475 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3476
3477 /* Parse and fetch high RSSI */
3478 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3479 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3480 goto fail;
3481 }
3482 pReqMsg->ap[i].high = nla_get_s32(
3483 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3484 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3485 pReqMsg->ap[i].high);
3486
3487 /* Parse and fetch channel */
3488 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3489 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3490 goto fail;
3491 }
3492 pReqMsg->ap[i].channel = nla_get_u32(
3493 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3494 hddLog(VOS_TRACE_LEVEL_INFO,
3495 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3496 i++;
3497 }
3498 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3499 if (!HAL_STATUS_SUCCESS(status)) {
3500 hddLog(VOS_TRACE_LEVEL_ERROR,
3501 FL("sme_SetBssHotlist failed(err=%d)"), status);
3502 vos_mem_free(pReqMsg);
3503 return -EINVAL;
3504 }
3505
Dino Myclee8843b32014-07-04 14:21:45 +05303506 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303507 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303508 return 0;
3509
3510fail:
3511 vos_mem_free(pReqMsg);
3512 return -EINVAL;
3513}
3514
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303515static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3516 struct wireless_dev *wdev,
3517 const void *data, int dataLen)
3518{
3519 int ret = 0;
3520
3521 vos_ssr_protect(__func__);
3522 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3523 dataLen);
3524 vos_ssr_unprotect(__func__);
3525
3526 return ret;
3527}
3528
3529static int __wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303530 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303531 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303532{
3533 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3534 struct net_device *dev = wdev->netdev;
3535 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3536 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3537 struct nlattr
3538 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3539 struct nlattr
3540 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3541 struct nlattr *apTh;
3542 eHalStatus status;
3543 int i = 0;
3544 int rem;
3545
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303546 ENTER();
3547
Dino Mycle6fb96c12014-06-10 11:52:40 +05303548 status = wlan_hdd_validate_context(pHddCtx);
3549 if (0 != status)
3550 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303551 return -EINVAL;
3552 }
Dino Myclee8843b32014-07-04 14:21:45 +05303553 /* check the EXTScan Capability */
3554 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3555 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3556 {
3557 hddLog(VOS_TRACE_LEVEL_ERROR,
3558 FL("EXTScan not enabled/supported by Firmware"));
3559 return -EINVAL;
3560 }
3561
Dino Mycle6fb96c12014-06-10 11:52:40 +05303562 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3563 data, dataLen,
3564 wlan_hdd_extscan_config_policy)) {
3565 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3566 return -EINVAL;
3567 }
3568
3569 /* Parse and fetch request Id */
3570 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3571 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3572 return -EINVAL;
3573 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303574 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303575 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303576 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303577 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3578 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303579 }
3580
Dino Myclee8843b32014-07-04 14:21:45 +05303581
3582
Dino Mycle6fb96c12014-06-10 11:52:40 +05303583 pReqMsg->requestId = nla_get_u32(
3584 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3585 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3586
3587 /* Parse and fetch RSSI sample size */
3588 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3589 {
3590 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3591 goto fail;
3592 }
3593 pReqMsg->rssiSampleSize = nla_get_u32(
3594 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3595 hddLog(VOS_TRACE_LEVEL_INFO,
3596 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3597
3598 /* Parse and fetch lost AP sample size */
3599 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3600 {
3601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3602 goto fail;
3603 }
3604 pReqMsg->lostApSampleSize = nla_get_u32(
3605 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3606 hddLog(VOS_TRACE_LEVEL_INFO,
3607 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3608 /* Parse and fetch minimum Breaching */
3609 if (!tb
3610 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3611 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3612 goto fail;
3613 }
3614 pReqMsg->minBreaching = nla_get_u32(
3615 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3616 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3617
3618 /* Parse and fetch number of APs */
3619 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3620 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3621 goto fail;
3622 }
3623 pReqMsg->numAp = nla_get_u32(
3624 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3625 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3626
3627 pReqMsg->sessionId = pAdapter->sessionId;
3628 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3629
3630 nla_for_each_nested(apTh,
3631 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3632 if(nla_parse(tb2,
3633 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3634 nla_data(apTh), nla_len(apTh),
3635 NULL)) {
3636 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3637 goto fail;
3638 }
3639
3640 /* Parse and fetch MAC address */
3641 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3642 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3643 goto fail;
3644 }
3645 memcpy(pReqMsg->ap[i].bssid, nla_data(
3646 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3647 sizeof(tSirMacAddr));
3648
3649 /* Parse and fetch low RSSI */
3650 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3651 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3652 goto fail;
3653 }
3654 pReqMsg->ap[i].low = nla_get_s32(
3655 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3656 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3657
3658 /* Parse and fetch high RSSI */
3659 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3660 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3661 goto fail;
3662 }
3663 pReqMsg->ap[i].high = nla_get_s32(
3664 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3665 hddLog(VOS_TRACE_LEVEL_INFO,
3666 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3667
3668 /* Parse and fetch channel */
3669 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3670 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3671 goto fail;
3672 }
3673 pReqMsg->ap[i].channel = nla_get_u32(
3674 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3675 hddLog(VOS_TRACE_LEVEL_INFO,
3676 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3677 i++;
3678 }
3679
3680 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3681 if (!HAL_STATUS_SUCCESS(status)) {
3682 hddLog(VOS_TRACE_LEVEL_ERROR,
3683 FL("sme_SetSignificantChange failed(err=%d)"), status);
3684 vos_mem_free(pReqMsg);
3685 return -EINVAL;
3686 }
Dino Myclee8843b32014-07-04 14:21:45 +05303687 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303688 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303689 return 0;
3690
3691fail:
3692 vos_mem_free(pReqMsg);
3693 return -EINVAL;
3694}
3695
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303696static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3697 struct wireless_dev *wdev,
3698 const void *data, int dataLen)
3699{
3700 int ret = 0;
3701
3702 vos_ssr_protect(__func__);
3703 ret = __wlan_hdd_cfg80211_extscan_set_significant_change(wiphy, wdev, data,
3704 dataLen);
3705 vos_ssr_unprotect(__func__);
3706
3707 return ret;
3708}
3709
3710static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303711 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303712 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303713{
3714 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3715 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3716 tANI_U8 numChannels = 0;
3717 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3718 tANI_U32 requestId;
3719 tWifiBand wifiBand;
3720 eHalStatus status;
3721 struct sk_buff *replySkb;
3722 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303723 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303724
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303725 ENTER();
3726
Dino Mycle6fb96c12014-06-10 11:52:40 +05303727 status = wlan_hdd_validate_context(pHddCtx);
3728 if (0 != status)
3729 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303730 return -EINVAL;
3731 }
Dino Myclee8843b32014-07-04 14:21:45 +05303732 /* check the EXTScan Capability */
3733 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3734 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3735 {
3736 hddLog(VOS_TRACE_LEVEL_ERROR,
3737 FL("EXTScan not enabled/supported by Firmware"));
3738 return -EINVAL;
3739 }
3740
Dino Mycle6fb96c12014-06-10 11:52:40 +05303741 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3742 data, dataLen,
3743 wlan_hdd_extscan_config_policy)) {
3744 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3745 return -EINVAL;
3746 }
3747
3748 /* Parse and fetch request Id */
3749 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3750 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3751 return -EINVAL;
3752 }
3753 requestId = nla_get_u32(
3754 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3755 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3756
3757 /* Parse and fetch wifi band */
3758 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3759 {
3760 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3761 return -EINVAL;
3762 }
3763 wifiBand = nla_get_u32(
3764 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3765 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3766
3767 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3768 wifiBand, ChannelList,
3769 &numChannels);
3770 if (eHAL_STATUS_SUCCESS != status) {
3771 hddLog(VOS_TRACE_LEVEL_ERROR,
3772 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3773 return -EINVAL;
3774 }
3775 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3776 for (i = 0; i < numChannels; i++)
3777 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3778
3779 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3780 sizeof(u32) * numChannels +
3781 NLMSG_HDRLEN);
3782
3783 if (!replySkb) {
3784 hddLog(VOS_TRACE_LEVEL_ERROR,
3785 FL("valid channels: buffer alloc fail"));
3786 return -EINVAL;
3787 }
3788 if (nla_put_u32(replySkb,
3789 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3790 numChannels) ||
3791 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3792 sizeof(u32) * numChannels, ChannelList)) {
3793
3794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3795 kfree_skb(replySkb);
3796 return -EINVAL;
3797 }
3798
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303799 ret = cfg80211_vendor_cmd_reply(replySkb);
3800
3801 EXIT();
3802 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303803}
3804
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303805static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3806 struct wireless_dev *wdev,
3807 const void *data, int dataLen)
3808{
3809 int ret = 0;
3810
3811 vos_ssr_protect(__func__);
3812 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
3813 dataLen);
3814 vos_ssr_unprotect(__func__);
3815
3816 return ret;
3817}
3818
3819static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303820 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303821 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303822{
Dino Myclee8843b32014-07-04 14:21:45 +05303823 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303824 struct net_device *dev = wdev->netdev;
3825 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3826 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3827 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3828 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3829 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3830 struct nlattr *buckets;
3831 struct nlattr *channels;
3832 int rem1;
3833 int rem2;
3834 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303835 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303836
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303837 ENTER();
3838
Dino Mycle6fb96c12014-06-10 11:52:40 +05303839 status = wlan_hdd_validate_context(pHddCtx);
3840 if (0 != status)
3841 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303842 return -EINVAL;
3843 }
Dino Myclee8843b32014-07-04 14:21:45 +05303844 /* check the EXTScan Capability */
3845 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3846 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3847 {
3848 hddLog(VOS_TRACE_LEVEL_ERROR,
3849 FL("EXTScan not enabled/supported by Firmware"));
3850 return -EINVAL;
3851 }
3852
Dino Mycle6fb96c12014-06-10 11:52:40 +05303853 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3854 data, dataLen,
3855 wlan_hdd_extscan_config_policy)) {
3856 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3857 return -EINVAL;
3858 }
3859
3860 /* Parse and fetch request Id */
3861 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3862 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3863 return -EINVAL;
3864 }
3865
Dino Myclee8843b32014-07-04 14:21:45 +05303866 pReqMsg = (tpSirEXTScanStartReqParams)
3867 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303868 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303869 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3870 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303871 }
3872
3873 pReqMsg->requestId = nla_get_u32(
3874 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3875 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3876
3877 pReqMsg->sessionId = pAdapter->sessionId;
3878 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3879
3880 /* Parse and fetch base period */
3881 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3882 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3883 goto fail;
3884 }
3885 pReqMsg->basePeriod = nla_get_u32(
3886 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3887 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3888 pReqMsg->basePeriod);
3889
3890 /* Parse and fetch max AP per scan */
3891 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3892 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3893 goto fail;
3894 }
3895 pReqMsg->maxAPperScan = nla_get_u32(
3896 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3897 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3898 pReqMsg->maxAPperScan);
3899
3900 /* Parse and fetch report threshold */
3901 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3902 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3903 goto fail;
3904 }
3905 pReqMsg->reportThreshold = nla_get_u8(
3906 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3907 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3908 pReqMsg->reportThreshold);
3909
3910 /* Parse and fetch number of buckets */
3911 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3912 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3913 goto fail;
3914 }
3915 pReqMsg->numBuckets = nla_get_u8(
3916 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3917 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3918 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3919 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3920 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3921 }
3922 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3923 pReqMsg->numBuckets);
3924 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3925 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3926 goto fail;
3927 }
3928
3929 nla_for_each_nested(buckets,
3930 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3931 if(nla_parse(bucket,
3932 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3933 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3934 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3935 goto fail;
3936 }
3937
3938 /* Parse and fetch bucket spec */
3939 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3940 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3941 goto fail;
3942 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303943
3944 pReqMsg->buckets[index].bucket = nla_get_u8(
3945 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3946
3947 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
3948 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303949
3950 /* Parse and fetch wifi band */
3951 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3952 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3953 goto fail;
3954 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303955 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303956 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3957 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303958 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303959
3960 /* Parse and fetch period */
3961 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3962 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3963 goto fail;
3964 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303965 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303966 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3967 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303968 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303969
3970 /* Parse and fetch report events */
3971 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3972 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3973 goto fail;
3974 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303975 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303976 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3977 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303978 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303979
3980 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303981 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
3982 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303983 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3984 goto fail;
3985 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303986 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303987 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3988 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303989 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303990
3991 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3992 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3993 goto fail;
3994 }
3995
3996 j = 0;
3997 nla_for_each_nested(channels,
3998 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3999 if(nla_parse(channel,
4000 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4001 nla_data(channels), nla_len(channels),
4002 NULL)) { //wlan_hdd_extscan_config_policy here
4003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4004 goto fail;
4005 }
4006
4007 /* Parse and fetch channel */
4008 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4009 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4010 goto fail;
4011 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304012 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304013 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4014 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304015 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304016
4017 /* Parse and fetch dwell time */
4018 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4019 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
4020 goto fail;
4021 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304022 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304023 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4024 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304025 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304026
4027 /* Parse and fetch channel spec passive */
4028 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4029 hddLog(VOS_TRACE_LEVEL_ERROR,
4030 FL("attr channel spec passive failed"));
4031 goto fail;
4032 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304033 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304034 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4035 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304036 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304037 j++;
4038 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304039 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304040 }
4041 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4042 if (!HAL_STATUS_SUCCESS(status)) {
4043 hddLog(VOS_TRACE_LEVEL_ERROR,
4044 FL("sme_EXTScanStart failed(err=%d)"), status);
4045 vos_mem_free(pReqMsg);
4046 return -EINVAL;
4047 }
4048
Dino Myclee8843b32014-07-04 14:21:45 +05304049 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304050 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304051 return 0;
4052
4053fail:
4054 vos_mem_free(pReqMsg);
4055 return -EINVAL;
4056}
4057
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304058static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4059 struct wireless_dev *wdev,
4060 const void *data, int dataLen)
4061{
4062 int ret = 0;
4063
4064 vos_ssr_protect(__func__);
4065 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4066 vos_ssr_unprotect(__func__);
4067
4068 return ret;
4069}
4070
4071static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304072 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304073 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304074{
Dino Myclee8843b32014-07-04 14:21:45 +05304075 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304076 struct net_device *dev = wdev->netdev;
4077 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4078 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4079 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4080 eHalStatus status;
4081
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304082 ENTER();
4083
Dino Mycle6fb96c12014-06-10 11:52:40 +05304084 status = wlan_hdd_validate_context(pHddCtx);
4085 if (0 != status)
4086 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304087 return -EINVAL;
4088 }
Dino Myclee8843b32014-07-04 14:21:45 +05304089 /* check the EXTScan Capability */
4090 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4091 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4092 {
4093 hddLog(VOS_TRACE_LEVEL_ERROR,
4094 FL("EXTScan not enabled/supported by Firmware"));
4095 return -EINVAL;
4096 }
4097
Dino Mycle6fb96c12014-06-10 11:52:40 +05304098 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4099 data, dataLen,
4100 wlan_hdd_extscan_config_policy)) {
4101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4102 return -EINVAL;
4103 }
4104
4105 /* Parse and fetch request Id */
4106 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4107 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4108 return -EINVAL;
4109 }
4110
Dino Myclee8843b32014-07-04 14:21:45 +05304111 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304112 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304113 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304114
Dino Myclee8843b32014-07-04 14:21:45 +05304115 reqMsg.sessionId = pAdapter->sessionId;
4116 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304117
Dino Myclee8843b32014-07-04 14:21:45 +05304118 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304119 if (!HAL_STATUS_SUCCESS(status)) {
4120 hddLog(VOS_TRACE_LEVEL_ERROR,
4121 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304122 return -EINVAL;
4123 }
4124
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304125 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304126 return 0;
4127}
4128
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304129static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4130 struct wireless_dev *wdev,
4131 const void *data, int dataLen)
4132{
4133 int ret = 0;
4134
4135 vos_ssr_protect(__func__);
4136 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4137 vos_ssr_unprotect(__func__);
4138
4139 return ret;
4140}
4141
4142static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304143 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304144 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304145{
Dino Myclee8843b32014-07-04 14:21:45 +05304146 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304147 struct net_device *dev = wdev->netdev;
4148 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4149 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4150 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4151 eHalStatus status;
4152
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304153 ENTER();
4154
Dino Mycle6fb96c12014-06-10 11:52:40 +05304155 status = wlan_hdd_validate_context(pHddCtx);
4156 if (0 != status)
4157 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304158 return -EINVAL;
4159 }
Dino Myclee8843b32014-07-04 14:21:45 +05304160 /* check the EXTScan Capability */
4161 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4162 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4163 {
4164 hddLog(VOS_TRACE_LEVEL_ERROR,
4165 FL("EXTScan not enabled/supported by Firmware"));
4166 return -EINVAL;
4167 }
4168
Dino Mycle6fb96c12014-06-10 11:52:40 +05304169 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4170 data, dataLen,
4171 wlan_hdd_extscan_config_policy)) {
4172 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4173 return -EINVAL;
4174 }
4175
4176 /* Parse and fetch request Id */
4177 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4179 return -EINVAL;
4180 }
4181
Dino Myclee8843b32014-07-04 14:21:45 +05304182 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304183 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304184 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304185
Dino Myclee8843b32014-07-04 14:21:45 +05304186 reqMsg.sessionId = pAdapter->sessionId;
4187 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304188
Dino Myclee8843b32014-07-04 14:21:45 +05304189 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304190 if (!HAL_STATUS_SUCCESS(status)) {
4191 hddLog(VOS_TRACE_LEVEL_ERROR,
4192 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304193 return -EINVAL;
4194 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304195 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304196 return 0;
4197}
4198
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304199static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4200 struct wireless_dev *wdev,
4201 const void *data, int dataLen)
4202{
4203 int ret = 0;
4204
4205 vos_ssr_protect(__func__);
4206 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4207 vos_ssr_unprotect(__func__);
4208
4209 return ret;
4210}
4211
4212static int __wlan_hdd_cfg80211_extscan_reset_significant_change(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304213 struct wiphy *wiphy,
4214 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304215 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304216{
Dino Myclee8843b32014-07-04 14:21:45 +05304217 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304218 struct net_device *dev = wdev->netdev;
4219 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4220 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4221 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4222 eHalStatus status;
4223
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304224 ENTER();
4225
Dino Mycle6fb96c12014-06-10 11:52:40 +05304226 status = wlan_hdd_validate_context(pHddCtx);
4227 if (0 != status)
4228 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304229 return -EINVAL;
4230 }
Dino Myclee8843b32014-07-04 14:21:45 +05304231 /* check the EXTScan Capability */
4232 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4233 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4234 {
4235 hddLog(VOS_TRACE_LEVEL_ERROR,
4236 FL("EXTScan not enabled/supported by Firmware"));
4237 return -EINVAL;
4238 }
4239
Dino Mycle6fb96c12014-06-10 11:52:40 +05304240 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4241 data, dataLen,
4242 wlan_hdd_extscan_config_policy)) {
4243 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4244 return -EINVAL;
4245 }
4246
4247 /* Parse and fetch request Id */
4248 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4249 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4250 return -EINVAL;
4251 }
4252
Dino Mycle6fb96c12014-06-10 11:52:40 +05304253
Dino Myclee8843b32014-07-04 14:21:45 +05304254 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304255 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304256 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304257
Dino Myclee8843b32014-07-04 14:21:45 +05304258 reqMsg.sessionId = pAdapter->sessionId;
4259 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304260
Dino Myclee8843b32014-07-04 14:21:45 +05304261 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304262 if (!HAL_STATUS_SUCCESS(status)) {
4263 hddLog(VOS_TRACE_LEVEL_ERROR,
4264 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304265 return -EINVAL;
4266 }
4267
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304268 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304269 return 0;
4270}
4271
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304272static int wlan_hdd_cfg80211_extscan_reset_significant_change(
4273 struct wiphy *wiphy,
4274 struct wireless_dev *wdev,
4275 const void *data, int dataLen)
4276{
4277 int ret = 0;
4278
4279 vos_ssr_protect(__func__);
4280 ret = __wlan_hdd_cfg80211_extscan_reset_significant_change(wiphy,
4281 wdev, data,
4282 dataLen);
4283 vos_ssr_unprotect(__func__);
4284
4285 return ret;
4286}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304287#endif /* WLAN_FEATURE_EXTSCAN */
4288
Atul Mittal115287b2014-07-08 13:26:33 +05304289/*EXT TDLS*/
4290static const struct nla_policy
4291wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4292{
4293 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4294 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4295 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4296 {.type = NLA_S32 },
4297 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4298 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4299
4300};
4301
4302static const struct nla_policy
4303wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4304{
4305 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4306
4307};
4308
4309static const struct nla_policy
4310wlan_hdd_tdls_config_state_change_policy[
4311 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4312{
4313 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4314 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4315 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304316 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4317 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4318 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304319
4320};
4321
4322static const struct nla_policy
4323wlan_hdd_tdls_config_get_status_policy[
4324 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4325{
4326 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4327 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4328 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304329 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4330 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4331 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304332
4333};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304334
4335static const struct nla_policy
4336wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4337{
4338 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4339};
4340
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304341static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304342 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304343 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304344 int data_len)
4345{
4346
4347 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4348 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4349
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304350 ENTER();
4351
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304352 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304353 return -EINVAL;
4354 }
4355 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
4356 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN disabled in ini"));
4357 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304358 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304359 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
4360 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN not supported by FW"));
4361 return -ENOTSUPP;
4362 }
4363
4364 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4365 data, data_len, wlan_hdd_mac_config)) {
4366 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4367 return -EINVAL;
4368 }
4369
4370 /* Parse and fetch mac address */
4371 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4372 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4373 return -EINVAL;
4374 }
4375
4376 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4377 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4378 VOS_MAC_ADDR_LAST_3_BYTES);
4379
Siddharth Bhal76972212014-10-15 16:22:51 +05304380 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4381
4382 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304383 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4384 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304385 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4386 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4387 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4388 {
4389 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4390 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4391 VOS_MAC_ADDRESS_LEN);
4392 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304393 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304394
Siddharth Bhal76972212014-10-15 16:22:51 +05304395 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
4396 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304397 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4398 }
4399
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304400 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304401 return 0;
4402}
4403
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304404static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4405 struct wireless_dev *wdev,
4406 const void *data,
4407 int data_len)
4408{
4409 int ret = 0;
4410
4411 vos_ssr_protect(__func__);
4412 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
4413 vos_ssr_unprotect(__func__);
4414
4415 return ret;
4416}
4417
4418static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304419 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304420 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304421 int data_len)
4422{
4423 u8 peer[6] = {0};
4424 struct net_device *dev = wdev->netdev;
4425 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4426 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4427 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4428 eHalStatus ret;
4429 tANI_S32 state;
4430 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304431 tANI_S32 global_operating_class = 0;
4432 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304433 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304434 int retVal;
4435
4436 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304437
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304438 if (!pAdapter) {
4439 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4440 return -EINVAL;
4441 }
4442
Atul Mittal115287b2014-07-08 13:26:33 +05304443 ret = wlan_hdd_validate_context(pHddCtx);
4444 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304445 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304446 return -EINVAL;
4447 }
4448 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304449 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304450 return -ENOTSUPP;
4451 }
4452 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4453 data, data_len,
4454 wlan_hdd_tdls_config_get_status_policy)) {
4455 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4456 return -EINVAL;
4457 }
4458
4459 /* Parse and fetch mac address */
4460 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4461 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4462 return -EINVAL;
4463 }
4464
4465 memcpy(peer, nla_data(
4466 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4467 sizeof(peer));
4468 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4469
4470 ret = wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
4471
4472 if (0 != ret) {
4473 hddLog(VOS_TRACE_LEVEL_ERROR,
4474 FL("get status Failed"));
4475 return -EINVAL;
4476 }
4477 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304478 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304479 NLMSG_HDRLEN);
4480
4481 if (!skb) {
4482 hddLog(VOS_TRACE_LEVEL_ERROR,
4483 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4484 return -EINVAL;
4485 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304486 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05304487 reason,
4488 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304489 global_operating_class,
4490 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304491 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304492 if (nla_put_s32(skb,
4493 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4494 state) ||
4495 nla_put_s32(skb,
4496 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4497 reason) ||
4498 nla_put_s32(skb,
4499 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4500 global_operating_class) ||
4501 nla_put_s32(skb,
4502 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4503 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304504
4505 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4506 goto nla_put_failure;
4507 }
4508
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304509 retVal = cfg80211_vendor_cmd_reply(skb);
4510 EXIT();
4511 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05304512
4513nla_put_failure:
4514 kfree_skb(skb);
4515 return -EINVAL;
4516}
4517
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304518static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4519 struct wireless_dev *wdev,
4520 const void *data,
4521 int data_len)
4522{
4523 int ret = 0;
4524
4525 vos_ssr_protect(__func__);
4526 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
4527 vos_ssr_unprotect(__func__);
4528
4529 return ret;
4530}
4531
Atul Mittal115287b2014-07-08 13:26:33 +05304532static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac,
4533 tANI_S32 state,
4534 tANI_S32 reason,
4535 void *ctx)
4536{
4537 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05304538 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304539 tANI_S32 global_operating_class = 0;
4540 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304541 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05304542
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304543 ENTER();
4544
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304545 if (!pAdapter) {
4546 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4547 return -EINVAL;
4548 }
4549
4550 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05304551 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304552 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304553 return -EINVAL;
4554 }
4555
4556 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304557 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304558 return -ENOTSUPP;
4559 }
4560 skb = cfg80211_vendor_event_alloc(
4561 pHddCtx->wiphy,
4562 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4563 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4564 GFP_KERNEL);
4565
4566 if (!skb) {
4567 hddLog(VOS_TRACE_LEVEL_ERROR,
4568 FL("cfg80211_vendor_event_alloc failed"));
4569 return -EINVAL;
4570 }
4571 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304572 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4573 reason,
4574 state,
4575 global_operating_class,
4576 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304577 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4578 MAC_ADDR_ARRAY(mac));
4579
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304580 if (nla_put(skb,
4581 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4582 VOS_MAC_ADDR_SIZE, mac) ||
4583 nla_put_s32(skb,
4584 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4585 state) ||
4586 nla_put_s32(skb,
4587 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4588 reason) ||
4589 nla_put_s32(skb,
4590 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4591 channel) ||
4592 nla_put_s32(skb,
4593 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4594 global_operating_class)
4595 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304596 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4597 goto nla_put_failure;
4598 }
4599
4600 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304601 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05304602 return (0);
4603
4604nla_put_failure:
4605 kfree_skb(skb);
4606 return -EINVAL;
4607}
4608
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304609static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304610 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304611 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304612 int data_len)
4613{
4614 u8 peer[6] = {0};
4615 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304616 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4617 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4618 eHalStatus status;
4619 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304620 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304621 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304622
4623 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304624
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304625 if (!dev) {
4626 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4627 return -EINVAL;
4628 }
4629
4630 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4631 if (!pAdapter) {
4632 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4633 return -EINVAL;
4634 }
4635
Atul Mittal115287b2014-07-08 13:26:33 +05304636 status = wlan_hdd_validate_context(pHddCtx);
4637 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304638 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304639 return -EINVAL;
4640 }
4641 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304642 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304643 return -ENOTSUPP;
4644 }
4645 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4646 data, data_len,
4647 wlan_hdd_tdls_config_enable_policy)) {
4648 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4649 return -EINVAL;
4650 }
4651
4652 /* Parse and fetch mac address */
4653 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4654 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4655 return -EINVAL;
4656 }
4657
4658 memcpy(peer, nla_data(
4659 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4660 sizeof(peer));
4661 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4662
4663 /* Parse and fetch channel */
4664 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4665 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4666 return -EINVAL;
4667 }
4668 pReqMsg.channel = nla_get_s32(
4669 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4670 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4671
4672 /* Parse and fetch global operating class */
4673 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4675 return -EINVAL;
4676 }
4677 pReqMsg.global_operating_class = nla_get_s32(
4678 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4679 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4680 pReqMsg.global_operating_class);
4681
4682 /* Parse and fetch latency ms */
4683 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4685 return -EINVAL;
4686 }
4687 pReqMsg.max_latency_ms = nla_get_s32(
4688 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4689 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4690 pReqMsg.max_latency_ms);
4691
4692 /* Parse and fetch required bandwidth kbps */
4693 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4695 return -EINVAL;
4696 }
4697
4698 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4699 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4700 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4701 pReqMsg.min_bandwidth_kbps);
4702
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304703 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05304704 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05304705 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304706 wlan_hdd_cfg80211_exttdls_callback);
4707
4708 EXIT();
4709 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304710}
4711
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304712static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4713 struct wireless_dev *wdev,
4714 const void *data,
4715 int data_len)
4716{
4717 int ret = 0;
4718
4719 vos_ssr_protect(__func__);
4720 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
4721 vos_ssr_unprotect(__func__);
4722
4723 return ret;
4724}
4725
4726static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304727 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304728 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304729 int data_len)
4730{
4731 u8 peer[6] = {0};
4732 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304733 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4734 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4735 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304736 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304737 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304738
4739 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304740
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304741 if (!dev) {
4742 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4743 return -EINVAL;
4744 }
4745
4746 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4747 if (!pAdapter) {
4748 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
4749 return -EINVAL;
4750 }
4751
Atul Mittal115287b2014-07-08 13:26:33 +05304752 status = wlan_hdd_validate_context(pHddCtx);
4753 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304754 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304755 return -EINVAL;
4756 }
4757 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304758 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304759 return -ENOTSUPP;
4760 }
4761 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4762 data, data_len,
4763 wlan_hdd_tdls_config_disable_policy)) {
4764 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4765 return -EINVAL;
4766 }
4767 /* Parse and fetch mac address */
4768 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4770 return -EINVAL;
4771 }
4772
4773 memcpy(peer, nla_data(
4774 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4775 sizeof(peer));
4776 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4777
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304778 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
4779
4780 EXIT();
4781 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304782}
4783
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304784static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4785 struct wireless_dev *wdev,
4786 const void *data,
4787 int data_len)
4788{
4789 int ret = 0;
4790
4791 vos_ssr_protect(__func__);
4792 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
4793 vos_ssr_unprotect(__func__);
4794
4795 return ret;
4796}
4797
Dasari Srinivas7875a302014-09-26 17:50:57 +05304798static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304799__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05304800 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304801 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05304802{
4803 struct net_device *dev = wdev->netdev;
4804 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4805 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4806 struct sk_buff *skb = NULL;
4807 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304808 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05304809
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304810 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304811
4812 ret = wlan_hdd_validate_context(pHddCtx);
4813 if (0 != ret)
4814 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304815 return ret;
4816 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05304817 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
4818 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
4819 fset |= WIFI_FEATURE_INFRA;
4820 }
4821
4822 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
4823 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
4824 fset |= WIFI_FEATURE_INFRA_5G;
4825 }
4826
4827#ifdef WLAN_FEATURE_P2P
4828 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
4829 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
4830 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
4831 fset |= WIFI_FEATURE_P2P;
4832 }
4833#endif
4834
4835 /* Soft-AP is supported currently by default */
4836 fset |= WIFI_FEATURE_SOFT_AP;
4837
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05304838 /* HOTSPOT is a supplicant feature, enable it by default */
4839 fset |= WIFI_FEATURE_HOTSPOT;
4840
Dasari Srinivas7875a302014-09-26 17:50:57 +05304841#ifdef WLAN_FEATURE_EXTSCAN
4842 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
4843 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
4844 hddLog(LOG1, FL("EXTScan is supported by firmware"));
4845 fset |= WIFI_FEATURE_EXTSCAN;
4846 }
4847#endif
4848
4849#ifdef WLAN_FEATURE_NAN
4850 if (sme_IsFeatureSupportedByFW(NAN)) {
4851 hddLog(LOG1, FL("NAN is supported by firmware"));
4852 fset |= WIFI_FEATURE_NAN;
4853 }
4854#endif
4855
4856 /* D2D RTT is not supported currently by default */
4857 if (sme_IsFeatureSupportedByFW(RTT)) {
4858 hddLog(LOG1, FL("RTT is supported by firmware"));
4859 fset |= WIFI_FEATURE_D2AP_RTT;
4860 }
4861
4862#ifdef FEATURE_WLAN_BATCH_SCAN
4863 if (fset & WIFI_FEATURE_EXTSCAN) {
4864 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
4865 fset &= ~WIFI_FEATURE_BATCH_SCAN;
4866 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
4867 hddLog(LOG1, FL("Batch scan is supported by firmware"));
4868 fset |= WIFI_FEATURE_BATCH_SCAN;
4869 }
4870#endif
4871
4872#ifdef FEATURE_WLAN_SCAN_PNO
4873 if (pHddCtx->cfg_ini->configPNOScanSupport &&
4874 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
4875 hddLog(LOG1, FL("PNO is supported by firmware"));
4876 fset |= WIFI_FEATURE_PNO;
4877 }
4878#endif
4879
4880 /* STA+STA is supported currently by default */
4881 fset |= WIFI_FEATURE_ADDITIONAL_STA;
4882
4883#ifdef FEATURE_WLAN_TDLS
4884 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
4885 sme_IsFeatureSupportedByFW(TDLS)) {
4886 hddLog(LOG1, FL("TDLS is supported by firmware"));
4887 fset |= WIFI_FEATURE_TDLS;
4888 }
4889
4890 /* TDLS_OFFCHANNEL is not supported currently by default */
4891#endif
4892
4893#ifdef WLAN_AP_STA_CONCURRENCY
4894 /* AP+STA concurrency is supported currently by default */
4895 fset |= WIFI_FEATURE_AP_STA;
4896#endif
4897
4898 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
4899 NLMSG_HDRLEN);
4900
4901 if (!skb) {
4902 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4903 return -EINVAL;
4904 }
4905 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
4906
4907 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
4908 hddLog(LOGE, FL("nla put fail"));
4909 goto nla_put_failure;
4910 }
4911
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304912 ret = cfg80211_vendor_cmd_reply(skb);
4913 EXIT();
4914 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05304915
4916nla_put_failure:
4917 kfree_skb(skb);
4918 return -EINVAL;
4919}
4920
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304921static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304922wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
4923 struct wireless_dev *wdev,
4924 const void *data, int data_len)
4925{
4926 int ret = 0;
4927
4928 vos_ssr_protect(__func__);
4929 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
4930 vos_ssr_unprotect(__func__);
4931
4932 return ret;
4933}
4934
4935static int
4936__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304937 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304938 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304939{
4940 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
4941 uint8_t i, feature_sets, max_feature_sets;
4942 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
4943 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304944 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4945 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304946
4947 ENTER();
4948
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304949 ret = wlan_hdd_validate_context(pHddCtx);
4950 if (0 != ret)
4951 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304952 return ret;
4953 }
4954
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304955 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
4956 data, data_len, NULL)) {
4957 hddLog(LOGE, FL("Invalid ATTR"));
4958 return -EINVAL;
4959 }
4960
4961 /* Parse and fetch max feature set */
4962 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
4963 hddLog(LOGE, FL("Attr max feature set size failed"));
4964 return -EINVAL;
4965 }
4966 max_feature_sets = nla_get_u32(
4967 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
4968 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
4969
4970 /* Fill feature combination matrix */
4971 feature_sets = 0;
4972 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4973 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4974 WIFI_FEATURE_P2P;
4975
4976 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4977 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4978 WIFI_FEATURE_SOFT_AP;
4979
4980 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4981 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
4982 WIFI_FEATURE_SOFT_AP;
4983
4984 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4985 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4986 WIFI_FEATURE_SOFT_AP |
4987 WIFI_FEATURE_P2P;
4988
4989 /* Add more feature combinations here */
4990
4991 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
4992 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
4993 hddLog(LOG1, "Feature set matrix");
4994 for (i = 0; i < feature_sets; i++)
4995 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
4996
4997 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4998 sizeof(u32) * feature_sets +
4999 NLMSG_HDRLEN);
5000
5001 if (reply_skb) {
5002 if (nla_put_u32(reply_skb,
5003 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5004 feature_sets) ||
5005 nla_put(reply_skb,
5006 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5007 sizeof(u32) * feature_sets, feature_set_matrix)) {
5008 hddLog(LOGE, FL("nla put fail"));
5009 kfree_skb(reply_skb);
5010 return -EINVAL;
5011 }
5012
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305013 ret = cfg80211_vendor_cmd_reply(reply_skb);
5014 EXIT();
5015 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305016 }
5017 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5018 return -ENOMEM;
5019
5020max_buffer_err:
5021 hddLog(LOGE, FL("Feature set max buffer size reached. feature_sets(%d) max(%d)"),
5022 feature_sets, WLAN_HDD_MAX_FEATURE_SET);
5023 return -EINVAL;
5024}
5025
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305026static int
5027wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5028 struct wireless_dev *wdev,
5029 const void *data, int data_len)
5030{
5031 int ret = 0;
5032
5033 vos_ssr_protect(__func__);
5034 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5035 data_len);
5036 vos_ssr_unprotect(__func__);
5037
5038 return ret;
5039}
5040
Agarwal Ashish738843c2014-09-25 12:27:56 +05305041static const struct nla_policy
5042wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5043 +1] =
5044{
5045 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5046};
5047
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305048static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305049 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305050 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305051 int data_len)
5052{
5053 struct net_device *dev = wdev->netdev;
5054 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5055 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5056 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5057 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5058 eHalStatus status;
5059 u32 dfsFlag = 0;
5060
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305061 ENTER();
5062
Agarwal Ashish738843c2014-09-25 12:27:56 +05305063 status = wlan_hdd_validate_context(pHddCtx);
5064 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305065 return -EINVAL;
5066 }
5067 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5068 data, data_len,
5069 wlan_hdd_set_no_dfs_flag_config_policy)) {
5070 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5071 return -EINVAL;
5072 }
5073
5074 /* Parse and fetch required bandwidth kbps */
5075 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5076 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5077 return -EINVAL;
5078 }
5079
5080 dfsFlag = nla_get_u32(
5081 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5082 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5083 dfsFlag);
5084
5085 pHddCtx->disable_dfs_flag = dfsFlag;
5086
5087 sme_disable_dfs_channel(hHal, dfsFlag);
5088 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305089
5090 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305091 return 0;
5092}
Atul Mittal115287b2014-07-08 13:26:33 +05305093
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305094static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5095 struct wireless_dev *wdev,
5096 const void *data,
5097 int data_len)
5098{
5099 int ret = 0;
5100
5101 vos_ssr_protect(__func__);
5102 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5103 vos_ssr_unprotect(__func__);
5104
5105 return ret;
5106
5107}
5108
Mukul Sharma2a271632014-10-13 14:59:01 +05305109const struct
5110nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5111{
5112 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5113 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5114};
5115
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305116static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305117 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305118{
5119
5120 u8 bssid[6] = {0};
5121 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5122 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5123 eHalStatus status = eHAL_STATUS_SUCCESS;
5124 v_U32_t isFwrRoamEnabled = FALSE;
5125 int ret;
5126
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305127 ENTER();
5128
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305129 ret = wlan_hdd_validate_context(pHddCtx);
5130 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305131 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305132 }
5133
5134 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5135 data, data_len,
5136 qca_wlan_vendor_attr);
5137 if (ret){
5138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5139 return -EINVAL;
5140 }
5141
5142 /* Parse and fetch Enable flag */
5143 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5144 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5145 return -EINVAL;
5146 }
5147
5148 isFwrRoamEnabled = nla_get_u32(
5149 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5150
5151 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5152
5153 /* Parse and fetch bssid */
5154 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5155 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5156 return -EINVAL;
5157 }
5158
5159 memcpy(bssid, nla_data(
5160 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5161 sizeof(bssid));
5162 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5163
5164 //Update roaming
5165 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305166 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305167 return status;
5168}
5169
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305170static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5171 struct wireless_dev *wdev, const void *data, int data_len)
5172{
5173 int ret = 0;
5174
5175 vos_ssr_protect(__func__);
5176 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5177 vos_ssr_unprotect(__func__);
5178
5179 return ret;
5180}
5181
Sunil Duttc69bccb2014-05-26 21:30:20 +05305182const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
5183{
Mukul Sharma2a271632014-10-13 14:59:01 +05305184 {
5185 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5186 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
5187 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5188 WIPHY_VENDOR_CMD_NEED_NETDEV |
5189 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305190 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05305191 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305192#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5193 {
5194 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5195 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
5196 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5197 WIPHY_VENDOR_CMD_NEED_NETDEV |
5198 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305199 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05305200 },
5201
5202 {
5203 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5204 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
5205 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5206 WIPHY_VENDOR_CMD_NEED_NETDEV |
5207 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305208 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05305209 },
5210
5211 {
5212 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5213 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
5214 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5215 WIPHY_VENDOR_CMD_NEED_NETDEV |
5216 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305217 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05305218 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305219#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305220#ifdef WLAN_FEATURE_EXTSCAN
5221 {
5222 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5223 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
5224 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5225 WIPHY_VENDOR_CMD_NEED_NETDEV |
5226 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305227 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05305228 },
5229 {
5230 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5231 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
5232 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5233 WIPHY_VENDOR_CMD_NEED_NETDEV |
5234 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305235 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05305236 },
5237 {
5238 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5239 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
5240 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5241 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305242 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05305243 },
5244 {
5245 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5246 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
5247 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5248 WIPHY_VENDOR_CMD_NEED_NETDEV |
5249 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305250 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05305251 },
5252 {
5253 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5254 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
5255 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5256 WIPHY_VENDOR_CMD_NEED_NETDEV |
5257 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305258 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05305259 },
5260 {
5261 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5262 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
5263 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5264 WIPHY_VENDOR_CMD_NEED_NETDEV |
5265 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305266 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305267 },
5268 {
5269 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5270 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
5271 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5272 WIPHY_VENDOR_CMD_NEED_NETDEV |
5273 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305274 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305275 },
5276 {
5277 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5278 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
5279 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5280 WIPHY_VENDOR_CMD_NEED_NETDEV |
5281 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305282 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305283 },
5284 {
5285 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5286 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
5287 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5288 WIPHY_VENDOR_CMD_NEED_NETDEV |
5289 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305290 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305291 },
5292#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305293/*EXT TDLS*/
5294 {
5295 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5296 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
5297 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5298 WIPHY_VENDOR_CMD_NEED_NETDEV |
5299 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305300 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05305301 },
5302 {
5303 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5304 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
5305 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5306 WIPHY_VENDOR_CMD_NEED_NETDEV |
5307 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305308 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05305309 },
5310 {
5311 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5312 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
5313 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5314 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305315 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05305316 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05305317 {
5318 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5319 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
5320 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5321 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305322 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05305323 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05305324 {
5325 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5326 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
5327 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5328 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305329 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05305330 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305331 {
5332 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5333 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
5334 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5335 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305336 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305337 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305338 {
5339 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5340 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
5341 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5342 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305343 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305344 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305345};
5346
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005347/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05305348static const
5349struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005350{
5351#ifdef FEATURE_WLAN_CH_AVOID
5352 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05305353 .vendor_id = QCA_NL80211_VENDOR_ID,
5354 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005355 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305356#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
5357#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5358 {
5359 /* Index = 1*/
5360 .vendor_id = QCA_NL80211_VENDOR_ID,
5361 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
5362 },
5363 {
5364 /* Index = 2*/
5365 .vendor_id = QCA_NL80211_VENDOR_ID,
5366 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
5367 },
5368 {
5369 /* Index = 3*/
5370 .vendor_id = QCA_NL80211_VENDOR_ID,
5371 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
5372 },
5373 {
5374 /* Index = 4*/
5375 .vendor_id = QCA_NL80211_VENDOR_ID,
5376 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
5377 },
5378 {
5379 /* Index = 5*/
5380 .vendor_id = QCA_NL80211_VENDOR_ID,
5381 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
5382 },
5383 {
5384 /* Index = 6*/
5385 .vendor_id = QCA_NL80211_VENDOR_ID,
5386 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
5387 },
5388#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305389#ifdef WLAN_FEATURE_EXTSCAN
5390 {
5391 .vendor_id = QCA_NL80211_VENDOR_ID,
5392 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
5393 },
5394 {
5395 .vendor_id = QCA_NL80211_VENDOR_ID,
5396 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
5397 },
5398 {
5399 .vendor_id = QCA_NL80211_VENDOR_ID,
5400 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
5401 },
5402 {
5403 .vendor_id = QCA_NL80211_VENDOR_ID,
5404 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
5405 },
5406 {
5407 .vendor_id = QCA_NL80211_VENDOR_ID,
5408 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
5409 },
5410 {
5411 .vendor_id = QCA_NL80211_VENDOR_ID,
5412 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
5413 },
5414 {
5415 .vendor_id = QCA_NL80211_VENDOR_ID,
5416 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
5417 },
5418 {
5419 .vendor_id = QCA_NL80211_VENDOR_ID,
5420 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
5421 },
5422 {
5423 .vendor_id = QCA_NL80211_VENDOR_ID,
5424 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
5425 },
5426 {
5427 .vendor_id = QCA_NL80211_VENDOR_ID,
5428 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
5429 },
5430 {
5431 .vendor_id = QCA_NL80211_VENDOR_ID,
5432 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
5433 },
5434 {
5435 .vendor_id = QCA_NL80211_VENDOR_ID,
5436 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
5437 },
5438 {
5439 .vendor_id = QCA_NL80211_VENDOR_ID,
5440 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
5441 },
5442#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305443/*EXT TDLS*/
5444 {
5445 .vendor_id = QCA_NL80211_VENDOR_ID,
5446 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
5447 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005448};
5449
Jeff Johnson295189b2012-06-20 16:38:30 -07005450/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305451 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305452 * This function is called by hdd_wlan_startup()
5453 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305454 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07005455 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305456struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07005457{
5458 struct wiphy *wiphy;
5459 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305460 /*
5461 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07005462 */
5463 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
5464
5465 if (!wiphy)
5466 {
5467 /* Print error and jump into err label and free the memory */
5468 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
5469 return NULL;
5470 }
5471
Sunil Duttc69bccb2014-05-26 21:30:20 +05305472
Jeff Johnson295189b2012-06-20 16:38:30 -07005473 return wiphy;
5474}
5475
5476/*
5477 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305478 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07005479 * private ioctl to change the band value
5480 */
5481int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
5482{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305483 int i, j;
5484 eNVChannelEnabledType channelEnabledState;
5485
Jeff Johnsone7245742012-09-05 17:12:55 -07005486 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305487
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305488 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005489 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305490
5491 if (NULL == wiphy->bands[i])
5492 {
5493 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5494 __func__, i);
5495 continue;
5496 }
5497
5498 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5499 {
5500 struct ieee80211_supported_band *band = wiphy->bands[i];
5501
5502 channelEnabledState = vos_nv_getChannelEnabledState(
5503 band->channels[j].hw_value);
5504
5505 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
5506 {
Abhishek Singh678227a2014-11-04 10:52:38 +05305507 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305508 continue;
5509 }
5510 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
5511 {
5512 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5513 continue;
5514 }
5515
5516 if (NV_CHANNEL_DISABLE == channelEnabledState ||
5517 NV_CHANNEL_INVALID == channelEnabledState)
5518 {
5519 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5520 }
5521 else if (NV_CHANNEL_DFS == channelEnabledState)
5522 {
5523 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5524 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
5525 }
5526 else
5527 {
5528 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
5529 |IEEE80211_CHAN_RADAR);
5530 }
5531 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005532 }
5533 return 0;
5534}
5535/*
5536 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305537 * This function is called by hdd_wlan_startup()
5538 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005539 * This function is used to initialize and register wiphy structure.
5540 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305541int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005542 struct wiphy *wiphy,
5543 hdd_config_t *pCfg
5544 )
5545{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305546 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305547 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5548
Jeff Johnsone7245742012-09-05 17:12:55 -07005549 ENTER();
5550
Jeff Johnson295189b2012-06-20 16:38:30 -07005551 /* Now bind the underlying wlan device with wiphy */
5552 set_wiphy_dev(wiphy, dev);
5553
5554 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005555
Kiet Lam6c583332013-10-14 05:37:09 +05305556#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005557 /* the flag for the other case would be initialzed in
5558 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005559 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305560#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005561
Amar Singhalfddc28c2013-09-05 13:03:40 -07005562 /* This will disable updating of NL channels from passive to
5563 * active if a beacon is received on passive channel. */
5564 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07005565
Amar Singhalfddc28c2013-09-05 13:03:40 -07005566
Amar Singhala49cbc52013-10-08 18:37:44 -07005567
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005568#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005569 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5570 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5571 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005572 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05305573 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005574#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005575
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005576#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005577 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005578#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005579 || pCfg->isFastRoamIniFeatureEnabled
5580#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005581#ifdef FEATURE_WLAN_ESE
5582 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005583#endif
5584 )
5585 {
5586 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5587 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005588#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005589#ifdef FEATURE_WLAN_TDLS
5590 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5591 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5592#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305593#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305594 if (pCfg->configPNOScanSupport)
5595 {
5596 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5597 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5598 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5599 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5600 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305601#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005602
Amar Singhalfddc28c2013-09-05 13:03:40 -07005603#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005604 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5605 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005606 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005607 driver need to determine what to do with both
5608 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005609
5610 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005611#else
5612 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005613#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005614
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305615 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5616
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05305617 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005618
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305619 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5620
Jeff Johnson295189b2012-06-20 16:38:30 -07005621 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305622 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07005623 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07005624 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5625 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005626 | BIT(NL80211_IFTYPE_AP);
5627
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305628 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005629 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305630#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5631 if( pCfg->enableMCC )
5632 {
5633 /* Currently, supports up to two channels */
5634 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005635
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305636 if( !pCfg->allowMCCGODiffBI )
5637 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005638
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305639 }
5640 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5641 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005642#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305643 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005644
Jeff Johnson295189b2012-06-20 16:38:30 -07005645 /* Before registering we need to update the ht capabilitied based
5646 * on ini values*/
5647 if( !pCfg->ShortGI20MhzEnable )
5648 {
5649 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5650 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5651 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5652 }
5653
5654 if( !pCfg->ShortGI40MhzEnable )
5655 {
5656 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5657 }
5658
5659 if( !pCfg->nChannelBondingMode5GHz )
5660 {
5661 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5662 }
5663
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305664 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305665 if (true == hdd_is_5g_supported(pHddCtx))
5666 {
5667 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5668 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305669
5670 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5671 {
5672
5673 if (NULL == wiphy->bands[i])
5674 {
5675 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5676 __func__, i);
5677 continue;
5678 }
5679
5680 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5681 {
5682 struct ieee80211_supported_band *band = wiphy->bands[i];
5683
5684 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5685 {
5686 // Enable social channels for P2P
5687 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5688 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5689 else
5690 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5691 continue;
5692 }
5693 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5694 {
5695 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5696 continue;
5697 }
5698 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005699 }
5700 /*Initialise the supported cipher suite details*/
5701 wiphy->cipher_suites = hdd_cipher_suites;
5702 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5703
5704 /*signal strength in mBm (100*dBm) */
5705 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5706
5707#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305708 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005709#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005710
Sunil Duttc69bccb2014-05-26 21:30:20 +05305711 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
5712 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005713 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
5714 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
5715
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305716 EXIT();
5717 return 0;
5718}
5719
5720/* In this function we are registering wiphy. */
5721int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
5722{
5723 ENTER();
5724 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005725 if (0 > wiphy_register(wiphy))
5726 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305727 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07005728 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
5729 return -EIO;
5730 }
5731
5732 EXIT();
5733 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305734}
Jeff Johnson295189b2012-06-20 16:38:30 -07005735
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305736/* In this function we are updating channel list when,
5737 regulatory domain is FCC and country code is US.
5738 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
5739 As per FCC smart phone is not a indoor device.
5740 GO should not opeate on indoor channels */
5741void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
5742{
5743 int j;
5744 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5745 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
5746 //Default counrtycode from NV at the time of wiphy initialization.
5747 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
5748 &defaultCountryCode[0]))
5749 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005750 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305751 }
5752 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
5753 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305754 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
5755 {
5756 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
5757 return;
5758 }
5759 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
5760 {
5761 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
5762 // Mark UNII -1 band channel as passive
5763 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
5764 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
5765 }
5766 }
5767}
5768
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305769/* This function registers for all frame which supplicant is interested in */
5770void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005771{
Jeff Johnson295189b2012-06-20 16:38:30 -07005772 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5773 /* Register for all P2P action, public action etc frames */
5774 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5775
Jeff Johnsone7245742012-09-05 17:12:55 -07005776 ENTER();
5777
Jeff Johnson295189b2012-06-20 16:38:30 -07005778 /* Right now we are registering these frame when driver is getting
5779 initialized. Once we will move to 2.6.37 kernel, in which we have
5780 frame register ops, we will move this code as a part of that */
5781 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305782 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07005783 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5784
5785 /* GAS Initial Response */
5786 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5787 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305788
Jeff Johnson295189b2012-06-20 16:38:30 -07005789 /* GAS Comeback Request */
5790 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5791 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5792
5793 /* GAS Comeback Response */
5794 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5795 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5796
5797 /* P2P Public Action */
5798 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305799 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005800 P2P_PUBLIC_ACTION_FRAME_SIZE );
5801
5802 /* P2P Action */
5803 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5804 (v_U8_t*)P2P_ACTION_FRAME,
5805 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07005806
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05305807 /* WNM BSS Transition Request frame */
5808 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5809 (v_U8_t*)WNM_BSS_ACTION_FRAME,
5810 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005811
5812 /* WNM-Notification */
5813 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5814 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5815 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005816}
5817
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305818void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005819{
Jeff Johnson295189b2012-06-20 16:38:30 -07005820 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5821 /* Register for all P2P action, public action etc frames */
5822 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5823
Jeff Johnsone7245742012-09-05 17:12:55 -07005824 ENTER();
5825
Jeff Johnson295189b2012-06-20 16:38:30 -07005826 /* Right now we are registering these frame when driver is getting
5827 initialized. Once we will move to 2.6.37 kernel, in which we have
5828 frame register ops, we will move this code as a part of that */
5829 /* GAS Initial Request */
5830
5831 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5832 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5833
5834 /* GAS Initial Response */
5835 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5836 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305837
Jeff Johnson295189b2012-06-20 16:38:30 -07005838 /* GAS Comeback Request */
5839 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5840 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5841
5842 /* GAS Comeback Response */
5843 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5844 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5845
5846 /* P2P Public Action */
5847 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305848 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005849 P2P_PUBLIC_ACTION_FRAME_SIZE );
5850
5851 /* P2P Action */
5852 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5853 (v_U8_t*)P2P_ACTION_FRAME,
5854 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005855 /* WNM-Notification */
5856 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5857 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5858 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005859}
5860
5861#ifdef FEATURE_WLAN_WAPI
5862void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
5863 const u8 *mac_addr, u8 *key , int key_Len)
5864{
5865 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5866 tCsrRoamSetKey setKey;
5867 v_BOOL_t isConnected = TRUE;
5868 int status = 0;
5869 v_U32_t roamId= 0xFF;
5870 tANI_U8 *pKeyPtr = NULL;
5871 int n = 0;
5872
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305873 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
5874 __func__, hdd_device_modetoString(pAdapter->device_mode),
5875 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005876
Gopichand Nakkalae7480202013-02-11 15:24:22 +05305877 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005878 setKey.keyId = key_index; // Store Key ID
5879 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
5880 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
5881 setKey.paeRole = 0 ; // the PAE role
5882 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
5883 {
5884 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
5885 }
5886 else
5887 {
5888 isConnected = hdd_connIsConnected(pHddStaCtx);
5889 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
5890 }
5891 setKey.keyLength = key_Len;
5892 pKeyPtr = setKey.Key;
5893 memcpy( pKeyPtr, key, key_Len);
5894
Arif Hussain6d2a3322013-11-17 19:50:10 -08005895 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005896 __func__, key_Len);
5897 for (n = 0 ; n < key_Len; n++)
5898 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
5899 __func__,n,setKey.Key[n]);
5900
5901 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
5902 if ( isConnected )
5903 {
5904 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
5905 pAdapter->sessionId, &setKey, &roamId );
5906 }
5907 if ( status != 0 )
5908 {
5909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5910 "[%4d] sme_RoamSetKey returned ERROR status= %d",
5911 __LINE__, status );
5912 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
5913 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05305914 /* Need to clear any trace of key value in the memory.
5915 * Thus zero out the memory even though it is local
5916 * variable.
5917 */
5918 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005919}
5920#endif /* FEATURE_WLAN_WAPI*/
5921
5922#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305923int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005924 beacon_data_t **ppBeacon,
5925 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005926#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305927int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005928 beacon_data_t **ppBeacon,
5929 struct cfg80211_beacon_data *params,
5930 int dtim_period)
5931#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305932{
Jeff Johnson295189b2012-06-20 16:38:30 -07005933 int size;
5934 beacon_data_t *beacon = NULL;
5935 beacon_data_t *old = NULL;
5936 int head_len,tail_len;
5937
Jeff Johnsone7245742012-09-05 17:12:55 -07005938 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005939 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305940 {
5941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5942 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005943 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305944 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005945
5946 old = pAdapter->sessionCtx.ap.beacon;
5947
5948 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305949 {
5950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5951 FL("session(%d) old and new heads points to NULL"),
5952 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005953 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305954 }
5955
5956 if (params->tail && !params->tail_len)
5957 {
5958 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5959 FL("tail_len is zero but tail is not NULL"));
5960 return -EINVAL;
5961 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005962
Jeff Johnson295189b2012-06-20 16:38:30 -07005963#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
5964 /* Kernel 3.0 is not updating dtim_period for set beacon */
5965 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305966 {
5967 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5968 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005969 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305970 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005971#endif
5972
5973 if(params->head)
5974 head_len = params->head_len;
5975 else
5976 head_len = old->head_len;
5977
5978 if(params->tail || !old)
5979 tail_len = params->tail_len;
5980 else
5981 tail_len = old->tail_len;
5982
5983 size = sizeof(beacon_data_t) + head_len + tail_len;
5984
5985 beacon = kzalloc(size, GFP_KERNEL);
5986
5987 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305988 {
5989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5990 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005991 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305992 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005993
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005994#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005995 if(params->dtim_period || !old )
5996 beacon->dtim_period = params->dtim_period;
5997 else
5998 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005999#else
6000 if(dtim_period || !old )
6001 beacon->dtim_period = dtim_period;
6002 else
6003 beacon->dtim_period = old->dtim_period;
6004#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306005
Jeff Johnson295189b2012-06-20 16:38:30 -07006006 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6007 beacon->tail = beacon->head + head_len;
6008 beacon->head_len = head_len;
6009 beacon->tail_len = tail_len;
6010
6011 if(params->head) {
6012 memcpy (beacon->head,params->head,beacon->head_len);
6013 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306014 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006015 if(old)
6016 memcpy (beacon->head,old->head,beacon->head_len);
6017 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306018
Jeff Johnson295189b2012-06-20 16:38:30 -07006019 if(params->tail) {
6020 memcpy (beacon->tail,params->tail,beacon->tail_len);
6021 }
6022 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306023 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006024 memcpy (beacon->tail,old->tail,beacon->tail_len);
6025 }
6026
6027 *ppBeacon = beacon;
6028
6029 kfree(old);
6030
6031 return 0;
6032
6033}
Jeff Johnson295189b2012-06-20 16:38:30 -07006034
6035v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
6036{
6037 int left = length;
6038 v_U8_t *ptr = pIes;
6039 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306040
Jeff Johnson295189b2012-06-20 16:38:30 -07006041 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306042 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006043 elem_id = ptr[0];
6044 elem_len = ptr[1];
6045 left -= 2;
6046 if(elem_len > left)
6047 {
6048 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006049 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006050 eid,elem_len,left);
6051 return NULL;
6052 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306053 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006054 {
6055 return ptr;
6056 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306057
Jeff Johnson295189b2012-06-20 16:38:30 -07006058 left -= elem_len;
6059 ptr += (elem_len + 2);
6060 }
6061 return NULL;
6062}
6063
Jeff Johnson295189b2012-06-20 16:38:30 -07006064/* Check if rate is 11g rate or not */
6065static int wlan_hdd_rate_is_11g(u8 rate)
6066{
Sanjay Devnani28322e22013-06-21 16:13:40 -07006067 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006068 u8 i;
6069 for (i = 0; i < 8; i++)
6070 {
6071 if(rate == gRateArray[i])
6072 return TRUE;
6073 }
6074 return FALSE;
6075}
6076
6077/* Check for 11g rate and set proper 11g only mode */
6078static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
6079 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
6080{
6081 u8 i, num_rates = pIe[0];
6082
6083 pIe += 1;
6084 for ( i = 0; i < num_rates; i++)
6085 {
6086 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
6087 {
6088 /* If rate set have 11g rate than change the mode to 11G */
6089 *pSapHw_mode = eSAP_DOT11_MODE_11g;
6090 if (pIe[i] & BASIC_RATE_MASK)
6091 {
6092 /* If we have 11g rate as basic rate, it means mode
6093 is 11g only mode.
6094 */
6095 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
6096 *pCheckRatesfor11g = FALSE;
6097 }
6098 }
6099 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6100 {
6101 *require_ht = TRUE;
6102 }
6103 }
6104 return;
6105}
6106
6107static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
6108{
6109 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6110 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6111 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6112 u8 checkRatesfor11g = TRUE;
6113 u8 require_ht = FALSE;
6114 u8 *pIe=NULL;
6115
6116 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
6117
6118 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6119 pBeacon->head_len, WLAN_EID_SUPP_RATES);
6120 if (pIe != NULL)
6121 {
6122 pIe += 1;
6123 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6124 &pConfig->SapHw_mode);
6125 }
6126
6127 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6128 WLAN_EID_EXT_SUPP_RATES);
6129 if (pIe != NULL)
6130 {
6131
6132 pIe += 1;
6133 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6134 &pConfig->SapHw_mode);
6135 }
6136
6137 if( pConfig->channel > 14 )
6138 {
6139 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
6140 }
6141
6142 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6143 WLAN_EID_HT_CAPABILITY);
6144
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306145 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006146 {
6147 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
6148 if(require_ht)
6149 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
6150 }
6151}
6152
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306153static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
6154 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
6155{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006156 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306157 v_U8_t *pIe = NULL;
6158 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6159
6160 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6161 pBeacon->tail, pBeacon->tail_len);
6162
6163 if (pIe)
6164 {
6165 ielen = pIe[1] + 2;
6166 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6167 {
6168 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
6169 }
6170 else
6171 {
6172 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
6173 return -EINVAL;
6174 }
6175 *total_ielen += ielen;
6176 }
6177 return 0;
6178}
6179
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006180static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
6181 v_U8_t *genie, v_U8_t *total_ielen)
6182{
6183 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6184 int left = pBeacon->tail_len;
6185 v_U8_t *ptr = pBeacon->tail;
6186 v_U8_t elem_id, elem_len;
6187 v_U16_t ielen = 0;
6188
6189 if ( NULL == ptr || 0 == left )
6190 return;
6191
6192 while (left >= 2)
6193 {
6194 elem_id = ptr[0];
6195 elem_len = ptr[1];
6196 left -= 2;
6197 if (elem_len > left)
6198 {
6199 hddLog( VOS_TRACE_LEVEL_ERROR,
6200 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
6201 elem_id, elem_len, left);
6202 return;
6203 }
6204 if (IE_EID_VENDOR == elem_id)
6205 {
6206 /* skipping the VSIE's which we don't want to include or
6207 * it will be included by existing code
6208 */
6209 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
6210#ifdef WLAN_FEATURE_WFD
6211 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
6212#endif
6213 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6214 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6215 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
6216 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6217 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
6218 {
6219 ielen = ptr[1] + 2;
6220 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6221 {
6222 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
6223 *total_ielen += ielen;
6224 }
6225 else
6226 {
6227 hddLog( VOS_TRACE_LEVEL_ERROR,
6228 "IE Length is too big "
6229 "IEs eid=%d elem_len=%d total_ie_lent=%d",
6230 elem_id, elem_len, *total_ielen);
6231 }
6232 }
6233 }
6234
6235 left -= elem_len;
6236 ptr += (elem_len + 2);
6237 }
6238 return;
6239}
6240
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006241#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006242static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6243 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006244#else
6245static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6246 struct cfg80211_beacon_data *params)
6247#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006248{
6249 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306250 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006251 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07006252 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006253
6254 genie = vos_mem_malloc(MAX_GENIE_LEN);
6255
6256 if(genie == NULL) {
6257
6258 return -ENOMEM;
6259 }
6260
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306261 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6262 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006263 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306264 hddLog(LOGE,
6265 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306266 ret = -EINVAL;
6267 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006268 }
6269
6270#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306271 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6272 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
6273 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306274 hddLog(LOGE,
6275 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306276 ret = -EINVAL;
6277 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006278 }
6279#endif
6280
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306281 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6282 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006283 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306284 hddLog(LOGE,
6285 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306286 ret = -EINVAL;
6287 goto done;
6288 }
6289
6290 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
6291 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006292 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07006293 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006294
6295 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6296 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
6297 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6298 {
6299 hddLog(LOGE,
6300 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006301 ret = -EINVAL;
6302 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006303 }
6304
6305 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6306 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6307 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6308 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6309 ==eHAL_STATUS_FAILURE)
6310 {
6311 hddLog(LOGE,
6312 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006313 ret = -EINVAL;
6314 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006315 }
6316
6317 // Added for ProResp IE
6318 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
6319 {
6320 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
6321 u8 probe_rsp_ie_len[3] = {0};
6322 u8 counter = 0;
6323 /* Check Probe Resp Length if it is greater then 255 then Store
6324 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
6325 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
6326 Store More then 255 bytes into One Variable.
6327 */
6328 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6329 {
6330 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6331 {
6332 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6333 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6334 }
6335 else
6336 {
6337 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6338 rem_probe_resp_ie_len = 0;
6339 }
6340 }
6341
6342 rem_probe_resp_ie_len = 0;
6343
6344 if (probe_rsp_ie_len[0] > 0)
6345 {
6346 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6347 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6348 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6349 probe_rsp_ie_len[0], NULL,
6350 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6351 {
6352 hddLog(LOGE,
6353 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006354 ret = -EINVAL;
6355 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006356 }
6357 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6358 }
6359
6360 if (probe_rsp_ie_len[1] > 0)
6361 {
6362 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6363 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6364 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6365 probe_rsp_ie_len[1], NULL,
6366 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6367 {
6368 hddLog(LOGE,
6369 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006370 ret = -EINVAL;
6371 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006372 }
6373 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6374 }
6375
6376 if (probe_rsp_ie_len[2] > 0)
6377 {
6378 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6379 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6380 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6381 probe_rsp_ie_len[2], NULL,
6382 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6383 {
6384 hddLog(LOGE,
6385 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006386 ret = -EINVAL;
6387 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006388 }
6389 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6390 }
6391
6392 if (probe_rsp_ie_len[1] == 0 )
6393 {
6394 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6395 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6396 eANI_BOOLEAN_FALSE) )
6397 {
6398 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006399 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006400 }
6401 }
6402
6403 if (probe_rsp_ie_len[2] == 0 )
6404 {
6405 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6406 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6407 eANI_BOOLEAN_FALSE) )
6408 {
6409 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006410 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006411 }
6412 }
6413
6414 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6415 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6416 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6417 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6418 == eHAL_STATUS_FAILURE)
6419 {
6420 hddLog(LOGE,
6421 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006422 ret = -EINVAL;
6423 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006424 }
6425 }
6426 else
6427 {
6428 // Reset WNI_CFG_PROBE_RSP Flags
6429 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
6430
6431 hddLog(VOS_TRACE_LEVEL_INFO,
6432 "%s: No Probe Response IE received in set beacon",
6433 __func__);
6434 }
6435
6436 // Added for AssocResp IE
6437 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
6438 {
6439 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6440 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
6441 params->assocresp_ies_len, NULL,
6442 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6443 {
6444 hddLog(LOGE,
6445 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006446 ret = -EINVAL;
6447 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006448 }
6449
6450 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6451 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
6452 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6453 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6454 == eHAL_STATUS_FAILURE)
6455 {
6456 hddLog(LOGE,
6457 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006458 ret = -EINVAL;
6459 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006460 }
6461 }
6462 else
6463 {
6464 hddLog(VOS_TRACE_LEVEL_INFO,
6465 "%s: No Assoc Response IE received in set beacon",
6466 __func__);
6467
6468 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6469 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6470 eANI_BOOLEAN_FALSE) )
6471 {
6472 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006473 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006474 }
6475 }
6476
Jeff Johnsone7245742012-09-05 17:12:55 -07006477done:
Jeff Johnson295189b2012-06-20 16:38:30 -07006478 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306479 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006480}
Jeff Johnson295189b2012-06-20 16:38:30 -07006481
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306482/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006483 * FUNCTION: wlan_hdd_validate_operation_channel
6484 * called by wlan_hdd_cfg80211_start_bss() and
6485 * wlan_hdd_cfg80211_set_channel()
6486 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306487 * channel list.
6488 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006489VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006490{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306491
Jeff Johnson295189b2012-06-20 16:38:30 -07006492 v_U32_t num_ch = 0;
6493 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6494 u32 indx = 0;
6495 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306496 v_U8_t fValidChannel = FALSE, count = 0;
6497 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306498
Jeff Johnson295189b2012-06-20 16:38:30 -07006499 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6500
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306501 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006502 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306503 /* Validate the channel */
6504 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006505 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306506 if ( channel == rfChannels[count].channelNum )
6507 {
6508 fValidChannel = TRUE;
6509 break;
6510 }
6511 }
6512 if (fValidChannel != TRUE)
6513 {
6514 hddLog(VOS_TRACE_LEVEL_ERROR,
6515 "%s: Invalid Channel [%d]", __func__, channel);
6516 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006517 }
6518 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306519 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006520 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306521 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6522 valid_ch, &num_ch))
6523 {
6524 hddLog(VOS_TRACE_LEVEL_ERROR,
6525 "%s: failed to get valid channel list", __func__);
6526 return VOS_STATUS_E_FAILURE;
6527 }
6528 for (indx = 0; indx < num_ch; indx++)
6529 {
6530 if (channel == valid_ch[indx])
6531 {
6532 break;
6533 }
6534 }
6535
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306536 if (indx >= num_ch)
6537 {
6538 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6539 {
6540 eCsrBand band;
6541 unsigned int freq;
6542
6543 sme_GetFreqBand(hHal, &band);
6544
6545 if (eCSR_BAND_5G == band)
6546 {
6547#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6548 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6549 {
6550 freq = ieee80211_channel_to_frequency(channel,
6551 IEEE80211_BAND_2GHZ);
6552 }
6553 else
6554 {
6555 freq = ieee80211_channel_to_frequency(channel,
6556 IEEE80211_BAND_5GHZ);
6557 }
6558#else
6559 freq = ieee80211_channel_to_frequency(channel);
6560#endif
6561 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6562 return VOS_STATUS_SUCCESS;
6563 }
6564 }
6565
6566 hddLog(VOS_TRACE_LEVEL_ERROR,
6567 "%s: Invalid Channel [%d]", __func__, channel);
6568 return VOS_STATUS_E_FAILURE;
6569 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006570 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306571
Jeff Johnson295189b2012-06-20 16:38:30 -07006572 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306573
Jeff Johnson295189b2012-06-20 16:38:30 -07006574}
6575
Viral Modi3a32cc52013-02-08 11:14:52 -08006576/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306577 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08006578 * This function is used to set the channel number
6579 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306580static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08006581 struct ieee80211_channel *chan,
6582 enum nl80211_channel_type channel_type
6583 )
6584{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306585 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006586 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006587 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006588 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306589 hdd_context_t *pHddCtx;
6590 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006591
6592 ENTER();
6593
6594 if( NULL == dev )
6595 {
6596 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006597 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006598 return -ENODEV;
6599 }
6600 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306601
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306602 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6603 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6604 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006605 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306606 "%s: device_mode = %s (%d) freq = %d", __func__,
6607 hdd_device_modetoString(pAdapter->device_mode),
6608 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306609
6610 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6611 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306612 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006613 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306614 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006615 }
6616
6617 /*
6618 * Do freq to chan conversion
6619 * TODO: for 11a
6620 */
6621
6622 channel = ieee80211_frequency_to_channel(freq);
6623
6624 /* Check freq range */
6625 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6626 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6627 {
6628 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006629 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006630 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6631 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6632 return -EINVAL;
6633 }
6634
6635 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6636
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306637 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6638 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006639 {
6640 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6641 {
6642 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006643 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006644 return -EINVAL;
6645 }
6646 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6647 "%s: set channel to [%d] for device mode =%d",
6648 __func__, channel,pAdapter->device_mode);
6649 }
6650 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006651 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006652 )
6653 {
6654 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6655 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6656 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6657
6658 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6659 {
6660 /* Link is up then return cant set channel*/
6661 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006662 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006663 return -EINVAL;
6664 }
6665
6666 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6667 pHddStaCtx->conn_info.operationChannel = channel;
6668 pRoamProfile->ChannelInfo.ChannelList =
6669 &pHddStaCtx->conn_info.operationChannel;
6670 }
6671 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006672 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006673 )
6674 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306675 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6676 {
6677 if(VOS_STATUS_SUCCESS !=
6678 wlan_hdd_validate_operation_channel(pAdapter,channel))
6679 {
6680 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006681 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306682 return -EINVAL;
6683 }
6684 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6685 }
6686 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006687 {
6688 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6689
6690 /* If auto channel selection is configured as enable/ 1 then ignore
6691 channel set by supplicant
6692 */
6693 if ( cfg_param->apAutoChannelSelection )
6694 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306695 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6696 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006697 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306698 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6699 __func__, hdd_device_modetoString(pAdapter->device_mode),
6700 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006701 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306702 else
6703 {
6704 if(VOS_STATUS_SUCCESS !=
6705 wlan_hdd_validate_operation_channel(pAdapter,channel))
6706 {
6707 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006708 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306709 return -EINVAL;
6710 }
6711 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6712 }
Viral Modi3a32cc52013-02-08 11:14:52 -08006713 }
6714 }
6715 else
6716 {
6717 hddLog(VOS_TRACE_LEVEL_FATAL,
6718 "%s: Invalid device mode failed to set valid channel", __func__);
6719 return -EINVAL;
6720 }
6721 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306722 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006723}
6724
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306725static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
6726 struct net_device *dev,
6727 struct ieee80211_channel *chan,
6728 enum nl80211_channel_type channel_type
6729 )
6730{
6731 int ret;
6732
6733 vos_ssr_protect(__func__);
6734 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
6735 vos_ssr_unprotect(__func__);
6736
6737 return ret;
6738}
6739
Jeff Johnson295189b2012-06-20 16:38:30 -07006740#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6741static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6742 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006743#else
6744static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6745 struct cfg80211_beacon_data *params,
6746 const u8 *ssid, size_t ssid_len,
6747 enum nl80211_hidden_ssid hidden_ssid)
6748#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006749{
6750 tsap_Config_t *pConfig;
6751 beacon_data_t *pBeacon = NULL;
6752 struct ieee80211_mgmt *pMgmt_frame;
6753 v_U8_t *pIe=NULL;
6754 v_U16_t capab_info;
6755 eCsrAuthType RSNAuthType;
6756 eCsrEncryptionType RSNEncryptType;
6757 eCsrEncryptionType mcRSNEncryptType;
6758 int status = VOS_STATUS_SUCCESS;
6759 tpWLAN_SAPEventCB pSapEventCallback;
6760 hdd_hostapd_state_t *pHostapdState;
6761 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
6762 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306763 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006764 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306765 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07006766 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08006767 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05306768 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07006769 v_BOOL_t MFPCapable = VOS_FALSE;
6770 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05306771 v_BOOL_t sapEnable11AC =
6772 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07006773 ENTER();
6774
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306775 iniConfig = pHddCtx->cfg_ini;
6776
Jeff Johnson295189b2012-06-20 16:38:30 -07006777 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
6778
6779 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6780
6781 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6782
6783 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6784
6785 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
6786
6787 //channel is already set in the set_channel Call back
6788 //pConfig->channel = pCommitConfig->channel;
6789
6790 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306791 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07006792 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
6793
6794 pConfig->dtim_period = pBeacon->dtim_period;
6795
Arif Hussain6d2a3322013-11-17 19:50:10 -08006796 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07006797 pConfig->dtim_period);
6798
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08006799 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07006800 {
6801 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006802 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05306803 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
6804 {
6805 tANI_BOOLEAN restartNeeded;
6806 pConfig->ieee80211d = 1;
6807 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
6808 sme_setRegInfo(hHal, pConfig->countryCode);
6809 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
6810 }
6811 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006812 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07006813 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07006814 pConfig->ieee80211d = 1;
6815 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
6816 sme_setRegInfo(hHal, pConfig->countryCode);
6817 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07006818 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006819 else
6820 {
6821 pConfig->ieee80211d = 0;
6822 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306823 /*
6824 * If auto channel is configured i.e. channel is 0,
6825 * so skip channel validation.
6826 */
6827 if( AUTO_CHANNEL_SELECT != pConfig->channel )
6828 {
6829 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
6830 {
6831 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006832 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306833 return -EINVAL;
6834 }
6835 }
6836 else
6837 {
6838 if(1 != pHddCtx->is_dynamic_channel_range_set)
6839 {
6840 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
6841 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
6842 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
6843 }
6844 pHddCtx->is_dynamic_channel_range_set = 0;
6845 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006846 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006847 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006848 {
6849 pConfig->ieee80211d = 0;
6850 }
6851 pConfig->authType = eSAP_AUTO_SWITCH;
6852
6853 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306854
6855 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07006856 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
6857
6858 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
6859
6860 /*Set wps station to configured*/
6861 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
6862
6863 if(pIe)
6864 {
6865 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
6866 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006867 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07006868 return -EINVAL;
6869 }
6870 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
6871 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006872 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07006873 /* Check 15 bit of WPS IE as it contain information for wps state
6874 * WPS state
6875 */
6876 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
6877 {
6878 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
6879 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
6880 {
6881 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
6882 }
6883 }
6884 }
6885 else
6886 {
6887 pConfig->wps_state = SAP_WPS_DISABLED;
6888 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306889 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07006890
c_hpothufe599e92014-06-16 11:38:55 +05306891 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6892 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6893 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
6894 eCSR_ENCRYPT_TYPE_NONE;
6895
Jeff Johnson295189b2012-06-20 16:38:30 -07006896 pConfig->RSNWPAReqIELength = 0;
6897 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306898 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006899 WLAN_EID_RSN);
6900 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306901 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006902 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6903 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6904 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306905 /* The actual processing may eventually be more extensive than
6906 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07006907 * by the app.
6908 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306909 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006910 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6911 &RSNEncryptType,
6912 &mcRSNEncryptType,
6913 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006914 &MFPCapable,
6915 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006916 pConfig->pRSNWPAReqIE[1]+2,
6917 pConfig->pRSNWPAReqIE );
6918
6919 if( VOS_STATUS_SUCCESS == status )
6920 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306921 /* Now copy over all the security attributes you have
6922 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006923 * */
6924 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6925 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6926 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6927 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306928 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006929 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006930 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6931 }
6932 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306933
Jeff Johnson295189b2012-06-20 16:38:30 -07006934 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6935 pBeacon->tail, pBeacon->tail_len);
6936
6937 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
6938 {
6939 if (pConfig->pRSNWPAReqIE)
6940 {
6941 /*Mixed mode WPA/WPA2*/
6942 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
6943 pConfig->RSNWPAReqIELength += pIe[1] + 2;
6944 }
6945 else
6946 {
6947 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6948 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6949 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306950 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006951 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6952 &RSNEncryptType,
6953 &mcRSNEncryptType,
6954 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006955 &MFPCapable,
6956 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006957 pConfig->pRSNWPAReqIE[1]+2,
6958 pConfig->pRSNWPAReqIE );
6959
6960 if( VOS_STATUS_SUCCESS == status )
6961 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306962 /* Now copy over all the security attributes you have
6963 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006964 * */
6965 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6966 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6967 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6968 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306969 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006970 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006971 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6972 }
6973 }
6974 }
6975
Jeff Johnson4416a782013-03-25 14:17:50 -07006976 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
6977 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
6978 return -EINVAL;
6979 }
6980
Jeff Johnson295189b2012-06-20 16:38:30 -07006981 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
6982
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006983#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006984 if (params->ssid != NULL)
6985 {
6986 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
6987 pConfig->SSIDinfo.ssid.length = params->ssid_len;
6988 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6989 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6990 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006991#else
6992 if (ssid != NULL)
6993 {
6994 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
6995 pConfig->SSIDinfo.ssid.length = ssid_len;
6996 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6997 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6998 }
6999#endif
7000
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307001 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07007002 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307003
Jeff Johnson295189b2012-06-20 16:38:30 -07007004 /* default value */
7005 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7006 pConfig->num_accept_mac = 0;
7007 pConfig->num_deny_mac = 0;
7008
7009 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7010 pBeacon->tail, pBeacon->tail_len);
7011
7012 /* pIe for black list is following form:
7013 type : 1 byte
7014 length : 1 byte
7015 OUI : 4 bytes
7016 acl type : 1 byte
7017 no of mac addr in black list: 1 byte
7018 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307019 */
7020 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007021 {
7022 pConfig->SapMacaddr_acl = pIe[6];
7023 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007024 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007025 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307026 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7027 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007028 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7029 for (i = 0; i < pConfig->num_deny_mac; i++)
7030 {
7031 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7032 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307033 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007034 }
7035 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7036 pBeacon->tail, pBeacon->tail_len);
7037
7038 /* pIe for white list is following form:
7039 type : 1 byte
7040 length : 1 byte
7041 OUI : 4 bytes
7042 acl type : 1 byte
7043 no of mac addr in white list: 1 byte
7044 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307045 */
7046 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007047 {
7048 pConfig->SapMacaddr_acl = pIe[6];
7049 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007050 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007051 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307052 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7053 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007054 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7055 for (i = 0; i < pConfig->num_accept_mac; i++)
7056 {
7057 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7058 acl_entry++;
7059 }
7060 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307061
Jeff Johnson295189b2012-06-20 16:38:30 -07007062 wlan_hdd_set_sapHwmode(pHostapdAdapter);
7063
Jeff Johnsone7245742012-09-05 17:12:55 -07007064#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007065 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307066 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
7067 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05307068 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
7069 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007070 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
7071 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307072 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
7073 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07007074 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307075 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07007076 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307077 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007078
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307079 /* If ACS disable and selected channel <= 14
7080 * OR
7081 * ACS enabled and ACS operating band is choosen as 2.4
7082 * AND
7083 * VHT in 2.4G Disabled
7084 * THEN
7085 * Fallback to 11N mode
7086 */
7087 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
7088 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05307089 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307090 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007091 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307092 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
7093 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007094 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
7095 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007096 }
7097#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307098
Jeff Johnson295189b2012-06-20 16:38:30 -07007099 // ht_capab is not what the name conveys,this is used for protection bitmap
7100 pConfig->ht_capab =
7101 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
7102
7103 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
7104 {
7105 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7106 return -EINVAL;
7107 }
7108
7109 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307110 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07007111 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
7112 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307113 pConfig->obssProtEnabled =
7114 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07007115
Chet Lanctot8cecea22014-02-11 19:09:36 -08007116#ifdef WLAN_FEATURE_11W
7117 pConfig->mfpCapable = MFPCapable;
7118 pConfig->mfpRequired = MFPRequired;
7119 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
7120 pConfig->mfpCapable, pConfig->mfpRequired);
7121#endif
7122
Arif Hussain6d2a3322013-11-17 19:50:10 -08007123 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07007124 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007125 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
7126 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7127 (int)pConfig->channel);
7128 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
7129 pConfig->SapHw_mode, pConfig->privacy,
7130 pConfig->authType);
7131 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
7132 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7133 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7134 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07007135
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307136 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007137 {
7138 //Bss already started. just return.
7139 //TODO Probably it should update some beacon params.
7140 hddLog( LOGE, "Bss Already started...Ignore the request");
7141 EXIT();
7142 return 0;
7143 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307144
Agarwal Ashish51325b52014-06-16 16:50:49 +05307145 if (vos_max_concurrent_connections_reached()) {
7146 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7147 return -EINVAL;
7148 }
7149
Jeff Johnson295189b2012-06-20 16:38:30 -07007150 pConfig->persona = pHostapdAdapter->device_mode;
7151
Peng Xu2446a892014-09-05 17:21:18 +05307152 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
7153 if ( NULL != psmeConfig)
7154 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307155 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05307156 sme_GetConfigParam(hHal, psmeConfig);
7157 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307158#ifdef WLAN_FEATURE_AP_HT40_24G
7159 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7160 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
7161 && pHddCtx->cfg_ini->apHT40_24GEnabled)
7162 {
7163 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
7164 sme_UpdateConfig (hHal, psmeConfig);
7165 }
7166#endif
Peng Xu2446a892014-09-05 17:21:18 +05307167 vos_mem_free(psmeConfig);
7168 }
Peng Xuafc34e32014-09-25 13:23:55 +05307169 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05307170
Jeff Johnson295189b2012-06-20 16:38:30 -07007171 pSapEventCallback = hdd_hostapd_SAPEventCB;
7172 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
7173 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
7174 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007175 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007176 return -EINVAL;
7177 }
7178
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307179 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07007180 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7181
7182 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307183
Jeff Johnson295189b2012-06-20 16:38:30 -07007184 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307185 {
7186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007187 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07007188 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07007189 VOS_ASSERT(0);
7190 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307191
Jeff Johnson295189b2012-06-20 16:38:30 -07007192 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05307193 /* Initialize WMM configuation */
7194 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307195 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007196
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007197#ifdef WLAN_FEATURE_P2P_DEBUG
7198 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
7199 {
7200 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
7201 {
7202 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7203 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007204 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007205 }
7206 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
7207 {
7208 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7209 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007210 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007211 }
7212 }
7213#endif
7214
Jeff Johnson295189b2012-06-20 16:38:30 -07007215 pHostapdState->bCommit = TRUE;
7216 EXIT();
7217
7218 return 0;
7219}
7220
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007221#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307222static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307223 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007224 struct beacon_parameters *params)
7225{
7226 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307227 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307228 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007229
7230 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307231
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307232 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7233 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
7234 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307235 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
7236 hdd_device_modetoString(pAdapter->device_mode),
7237 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007238
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307239 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7240 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307241 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007242 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307243 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007244 }
7245
Agarwal Ashish51325b52014-06-16 16:50:49 +05307246 if (vos_max_concurrent_connections_reached()) {
7247 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7248 return -EINVAL;
7249 }
7250
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307251 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007252 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007253 )
7254 {
7255 beacon_data_t *old,*new;
7256
7257 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307258
Jeff Johnson295189b2012-06-20 16:38:30 -07007259 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307260 {
7261 hddLog(VOS_TRACE_LEVEL_WARN,
7262 FL("already beacon info added to session(%d)"),
7263 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007264 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307265 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007266
7267 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7268
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307269 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07007270 {
7271 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007272 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007273 return -EINVAL;
7274 }
7275
7276 pAdapter->sessionCtx.ap.beacon = new;
7277
7278 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7279 }
7280
7281 EXIT();
7282 return status;
7283}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307284
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307285static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
7286 struct net_device *dev,
7287 struct beacon_parameters *params)
7288{
7289 int ret;
7290
7291 vos_ssr_protect(__func__);
7292 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
7293 vos_ssr_unprotect(__func__);
7294
7295 return ret;
7296}
7297
7298static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007299 struct net_device *dev,
7300 struct beacon_parameters *params)
7301{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307302 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307303 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7304 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307305 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007306
7307 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307308
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307309 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7310 TRACE_CODE_HDD_CFG80211_SET_BEACON,
7311 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
7312 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7313 __func__, hdd_device_modetoString(pAdapter->device_mode),
7314 pAdapter->device_mode);
7315
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307316 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7317 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307318 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007319 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307320 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007321 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307322
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307323 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007324 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307325 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007326 {
7327 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307328
Jeff Johnson295189b2012-06-20 16:38:30 -07007329 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307330
Jeff Johnson295189b2012-06-20 16:38:30 -07007331 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307332 {
7333 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7334 FL("session(%d) old and new heads points to NULL"),
7335 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007336 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307337 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007338
7339 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7340
7341 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307342 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007343 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007344 return -EINVAL;
7345 }
7346
7347 pAdapter->sessionCtx.ap.beacon = new;
7348
7349 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7350 }
7351
7352 EXIT();
7353 return status;
7354}
7355
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307356static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
7357 struct net_device *dev,
7358 struct beacon_parameters *params)
7359{
7360 int ret;
7361
7362 vos_ssr_protect(__func__);
7363 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
7364 vos_ssr_unprotect(__func__);
7365
7366 return ret;
7367}
7368
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007369#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7370
7371#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307372static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007373 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007374#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307375static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007376 struct net_device *dev)
7377#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007378{
7379 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07007380 hdd_context_t *pHddCtx = NULL;
7381 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307382 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307383 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007384
7385 ENTER();
7386
7387 if (NULL == pAdapter)
7388 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307389 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007390 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007391 return -ENODEV;
7392 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007393
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307394 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7395 TRACE_CODE_HDD_CFG80211_STOP_AP,
7396 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307397 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7398 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307399 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007400 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307401 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07007402 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007403
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007404 pScanInfo = &pHddCtx->scan_info;
7405
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307406 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7407 __func__, hdd_device_modetoString(pAdapter->device_mode),
7408 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007409
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307410 ret = wlan_hdd_scan_abort(pAdapter);
7411
Girish Gowli4bf7a632014-06-12 13:42:11 +05307412 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07007413 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7415 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307416
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307417 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07007418 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7420 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08007421
Jeff Johnsone7245742012-09-05 17:12:55 -07007422 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307423 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07007424 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307425 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07007426 }
7427
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05307428 /* Delete all associated STAs before stopping AP/P2P GO */
7429 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05307430 hdd_hostapd_stop(dev);
7431
Jeff Johnson295189b2012-06-20 16:38:30 -07007432 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007433 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007434 )
7435 {
7436 beacon_data_t *old;
7437
7438 old = pAdapter->sessionCtx.ap.beacon;
7439
7440 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307441 {
7442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7443 FL("session(%d) beacon data points to NULL"),
7444 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007445 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307446 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007447
Jeff Johnson295189b2012-06-20 16:38:30 -07007448 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007449
7450 mutex_lock(&pHddCtx->sap_lock);
7451 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7452 {
Jeff Johnson4416a782013-03-25 14:17:50 -07007453 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007454 {
7455 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7456
7457 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7458
7459 if (!VOS_IS_STATUS_SUCCESS(status))
7460 {
7461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007462 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007463 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307464 }
7465 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007466 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307467 /* BSS stopped, clear the active sessions for this device mode */
7468 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007469 }
7470 mutex_unlock(&pHddCtx->sap_lock);
7471
7472 if(status != VOS_STATUS_SUCCESS)
7473 {
7474 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007475 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007476 return -EINVAL;
7477 }
7478
Jeff Johnson4416a782013-03-25 14:17:50 -07007479 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007480 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
7481 ==eHAL_STATUS_FAILURE)
7482 {
7483 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007484 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007485 }
7486
Jeff Johnson4416a782013-03-25 14:17:50 -07007487 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007488 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7489 eANI_BOOLEAN_FALSE) )
7490 {
7491 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007492 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007493 }
7494
7495 // Reset WNI_CFG_PROBE_RSP Flags
7496 wlan_hdd_reset_prob_rspies(pAdapter);
7497
7498 pAdapter->sessionCtx.ap.beacon = NULL;
7499 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007500#ifdef WLAN_FEATURE_P2P_DEBUG
7501 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7502 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7503 {
7504 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7505 "GO got removed");
7506 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7507 }
7508#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007509 }
7510 EXIT();
7511 return status;
7512}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007513
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307514#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7515static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7516 struct net_device *dev)
7517{
7518 int ret;
7519
7520 vos_ssr_protect(__func__);
7521 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7522 vos_ssr_unprotect(__func__);
7523
7524 return ret;
7525}
7526#else
7527static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7528 struct net_device *dev)
7529{
7530 int ret;
7531
7532 vos_ssr_protect(__func__);
7533 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7534 vos_ssr_unprotect(__func__);
7535
7536 return ret;
7537}
7538#endif
7539
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007540#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7541
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307542static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307543 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007544 struct cfg80211_ap_settings *params)
7545{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307546 hdd_adapter_t *pAdapter;
7547 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307548 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007549
7550 ENTER();
7551
Girish Gowlib143d7a2015-02-18 19:39:55 +05307552 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007553 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05307555 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307556 return -ENODEV;
7557 }
7558
7559 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7560 if (NULL == pAdapter)
7561 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307563 "%s: HDD adapter is Null", __func__);
7564 return -ENODEV;
7565 }
7566
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307567 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7568 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
7569 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307570 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7571 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307572 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307573 "%s: HDD adapter magic is invalid", __func__);
7574 return -ENODEV;
7575 }
7576
7577 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307578 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307579 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307580 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307581 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307582 }
7583
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307584 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7585 __func__, hdd_device_modetoString(pAdapter->device_mode),
7586 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307587
7588 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007589 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007590 )
7591 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307592 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007593
7594 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307595
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007596 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307597 {
7598 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7599 FL("already beacon info added to session(%d)"),
7600 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007601 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307602 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007603
Girish Gowlib143d7a2015-02-18 19:39:55 +05307604#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7605 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7606 &new,
7607 &params->beacon);
7608#else
7609 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7610 &new,
7611 &params->beacon,
7612 params->dtim_period);
7613#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007614
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307615 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007616 {
7617 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307618 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007619 return -EINVAL;
7620 }
7621 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007622#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007623 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7624#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7625 params->channel, params->channel_type);
7626#else
7627 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7628#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007629#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007630 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
7631 params->ssid_len, params->hidden_ssid);
7632 }
7633
7634 EXIT();
7635 return status;
7636}
7637
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307638static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7639 struct net_device *dev,
7640 struct cfg80211_ap_settings *params)
7641{
7642 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007643
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307644 vos_ssr_protect(__func__);
7645 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
7646 vos_ssr_unprotect(__func__);
7647
7648 return ret;
7649}
7650
7651static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007652 struct net_device *dev,
7653 struct cfg80211_beacon_data *params)
7654{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307655 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307656 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307657 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007658
7659 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307660
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307661 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7662 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7663 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007664 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007665 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307666
7667 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7668 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307669 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007670 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307671 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007672 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007673
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307674 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007675 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307676 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007677 {
7678 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307679
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007680 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307681
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007682 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307683 {
7684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7685 FL("session(%d) beacon data points to NULL"),
7686 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007687 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307688 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007689
7690 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
7691
7692 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307693 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007694 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007695 return -EINVAL;
7696 }
7697
7698 pAdapter->sessionCtx.ap.beacon = new;
7699
7700 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
7701 }
7702
7703 EXIT();
7704 return status;
7705}
7706
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307707static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
7708 struct net_device *dev,
7709 struct cfg80211_beacon_data *params)
7710{
7711 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007712
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307713 vos_ssr_protect(__func__);
7714 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
7715 vos_ssr_unprotect(__func__);
7716
7717 return ret;
7718}
7719
7720#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007721
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307722static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007723 struct net_device *dev,
7724 struct bss_parameters *params)
7725{
7726 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307727 hdd_context_t *pHddCtx;
7728 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007729
7730 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307731
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307732 if (NULL == pAdapter)
7733 {
7734 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7735 "%s: HDD adapter is Null", __func__);
7736 return -ENODEV;
7737 }
7738 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307739 ret = wlan_hdd_validate_context(pHddCtx);
7740 if (0 != ret)
7741 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307742 return ret;
7743 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307744 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7745 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
7746 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307747 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7748 __func__, hdd_device_modetoString(pAdapter->device_mode),
7749 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007750
7751 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007752 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307753 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007754 {
7755 /* ap_isolate == -1 means that in change bss, upper layer doesn't
7756 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307757 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07007758 {
7759 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307760 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007761 }
7762
7763 EXIT();
7764 return 0;
7765}
7766
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307767static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
7768 struct net_device *dev,
7769 struct bss_parameters *params)
7770{
7771 int ret;
7772
7773 vos_ssr_protect(__func__);
7774 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
7775 vos_ssr_unprotect(__func__);
7776
7777 return ret;
7778}
Kiet Lam10841362013-11-01 11:36:50 +05307779/* FUNCTION: wlan_hdd_change_country_code_cd
7780* to wait for contry code completion
7781*/
7782void* wlan_hdd_change_country_code_cb(void *pAdapter)
7783{
7784 hdd_adapter_t *call_back_pAdapter = pAdapter;
7785 complete(&call_back_pAdapter->change_country_code);
7786 return NULL;
7787}
7788
Jeff Johnson295189b2012-06-20 16:38:30 -07007789/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307790 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07007791 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
7792 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307793int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007794 struct net_device *ndev,
7795 enum nl80211_iftype type,
7796 u32 *flags,
7797 struct vif_params *params
7798 )
7799{
7800 struct wireless_dev *wdev;
7801 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007802 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07007803 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007804 tCsrRoamProfile *pRoamProfile = NULL;
7805 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307806 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007807 eMib_dot11DesiredBssType connectedBssType;
7808 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307809 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007810
7811 ENTER();
7812
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307813 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007814 {
7815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7816 "%s: Adapter context is null", __func__);
7817 return VOS_STATUS_E_FAILURE;
7818 }
7819
7820 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7821 if (!pHddCtx)
7822 {
7823 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7824 "%s: HDD context is null", __func__);
7825 return VOS_STATUS_E_FAILURE;
7826 }
7827
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307828 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7829 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
7830 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307831 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307832 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007833 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307834 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007835 }
7836
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307837 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7838 __func__, hdd_device_modetoString(pAdapter->device_mode),
7839 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007840
Agarwal Ashish51325b52014-06-16 16:50:49 +05307841 if (vos_max_concurrent_connections_reached()) {
7842 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7843 return -EINVAL;
7844 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307845 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007846 wdev = ndev->ieee80211_ptr;
7847
7848#ifdef WLAN_BTAMP_FEATURE
7849 if((NL80211_IFTYPE_P2P_CLIENT == type)||
7850 (NL80211_IFTYPE_ADHOC == type)||
7851 (NL80211_IFTYPE_AP == type)||
7852 (NL80211_IFTYPE_P2P_GO == type))
7853 {
7854 pHddCtx->isAmpAllowed = VOS_FALSE;
7855 // stop AMP traffic
7856 status = WLANBAP_StopAmp();
7857 if(VOS_STATUS_SUCCESS != status )
7858 {
7859 pHddCtx->isAmpAllowed = VOS_TRUE;
7860 hddLog(VOS_TRACE_LEVEL_FATAL,
7861 "%s: Failed to stop AMP", __func__);
7862 return -EINVAL;
7863 }
7864 }
7865#endif //WLAN_BTAMP_FEATURE
7866 /* Reset the current device mode bit mask*/
7867 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7868
7869 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007870 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07007871 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07007872 )
7873 {
7874 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007875 if (!pWextState)
7876 {
7877 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7878 "%s: pWextState is null", __func__);
7879 return VOS_STATUS_E_FAILURE;
7880 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007881 pRoamProfile = &pWextState->roamProfile;
7882 LastBSSType = pRoamProfile->BSSType;
7883
7884 switch (type)
7885 {
7886 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007887 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007888 hddLog(VOS_TRACE_LEVEL_INFO,
7889 "%s: setting interface Type to INFRASTRUCTURE", __func__);
7890 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07007891#ifdef WLAN_FEATURE_11AC
7892 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
7893 {
7894 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
7895 }
7896#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307897 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07007898 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007899 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007900 //Check for sub-string p2p to confirm its a p2p interface
7901 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307902 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007903 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7904 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7905 }
7906 else
7907 {
7908 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007909 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007910 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007911 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05307912
Jeff Johnson295189b2012-06-20 16:38:30 -07007913 case NL80211_IFTYPE_ADHOC:
7914 hddLog(VOS_TRACE_LEVEL_INFO,
7915 "%s: setting interface Type to ADHOC", __func__);
7916 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
7917 pRoamProfile->phyMode =
7918 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07007919 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007920 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05307921 hdd_set_ibss_ops( pAdapter );
7922 hdd_ibss_init_tx_rx( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007923 break;
7924
7925 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007926 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007927 {
7928 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7929 "%s: setting interface Type to %s", __func__,
7930 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
7931
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007932 //Cancel any remain on channel for GO mode
7933 if (NL80211_IFTYPE_P2P_GO == type)
7934 {
7935 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
7936 }
Mohit Khanna0f232092012-09-11 14:46:08 -07007937 if (NL80211_IFTYPE_AP == type)
7938 {
7939 /* As Loading WLAN Driver one interface being created for p2p device
7940 * address. This will take one HW STA and the max number of clients
7941 * that can connect to softAP will be reduced by one. so while changing
7942 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
7943 * interface as it is not required in SoftAP mode.
7944 */
7945
7946 // Get P2P Adapter
7947 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
7948
7949 if (pP2pAdapter)
7950 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307951 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05307952 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07007953 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
7954 }
7955 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05307956 //Disable IMPS & BMPS for SAP/GO
7957 if(VOS_STATUS_E_FAILURE ==
7958 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
7959 {
7960 //Fail to Exit BMPS
7961 VOS_ASSERT(0);
7962 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05307963
7964 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
7965
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307966#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07007967
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307968 /* A Mutex Lock is introduced while changing the mode to
7969 * protect the concurrent access for the Adapters by TDLS
7970 * module.
7971 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307972 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307973#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007974 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05307975 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07007976 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07007977 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7978 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307979#ifdef FEATURE_WLAN_TDLS
7980 mutex_unlock(&pHddCtx->tdls_lock);
7981#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007982 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
7983 (pConfig->apRandomBssidEnabled))
7984 {
7985 /* To meet Android requirements create a randomized
7986 MAC address of the form 02:1A:11:Fx:xx:xx */
7987 get_random_bytes(&ndev->dev_addr[3], 3);
7988 ndev->dev_addr[0] = 0x02;
7989 ndev->dev_addr[1] = 0x1A;
7990 ndev->dev_addr[2] = 0x11;
7991 ndev->dev_addr[3] |= 0xF0;
7992 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
7993 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08007994 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
7995 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007996 }
7997
Jeff Johnson295189b2012-06-20 16:38:30 -07007998 hdd_set_ap_ops( pAdapter->dev );
7999
Kiet Lam10841362013-11-01 11:36:50 +05308000 /* This is for only SAP mode where users can
8001 * control country through ini.
8002 * P2P GO follows station country code
8003 * acquired during the STA scanning. */
8004 if((NL80211_IFTYPE_AP == type) &&
8005 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
8006 {
8007 int status = 0;
8008 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
8009 "%s: setting country code from INI ", __func__);
8010 init_completion(&pAdapter->change_country_code);
8011 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
8012 (void *)(tSmeChangeCountryCallback)
8013 wlan_hdd_change_country_code_cb,
8014 pConfig->apCntryCode, pAdapter,
8015 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308016 eSIR_FALSE,
8017 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05308018 if (eHAL_STATUS_SUCCESS == status)
8019 {
8020 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308021 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05308022 &pAdapter->change_country_code,
8023 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308024 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05308025 {
8026 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308027 FL("SME Timed out while setting country code %ld"),
8028 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08008029
8030 if (pHddCtx->isLogpInProgress)
8031 {
8032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8033 "%s: LOGP in Progress. Ignore!!!", __func__);
8034 return -EAGAIN;
8035 }
Kiet Lam10841362013-11-01 11:36:50 +05308036 }
8037 }
8038 else
8039 {
8040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008041 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05308042 return -EINVAL;
8043 }
8044 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008045 status = hdd_init_ap_mode(pAdapter);
8046 if(status != VOS_STATUS_SUCCESS)
8047 {
8048 hddLog(VOS_TRACE_LEVEL_FATAL,
8049 "%s: Error initializing the ap mode", __func__);
8050 return -EINVAL;
8051 }
8052 hdd_set_conparam(1);
8053
Jeff Johnson295189b2012-06-20 16:38:30 -07008054 /*interface type changed update in wiphy structure*/
8055 if(wdev)
8056 {
8057 wdev->iftype = type;
8058 pHddCtx->change_iface = type;
8059 }
8060 else
8061 {
8062 hddLog(VOS_TRACE_LEVEL_ERROR,
8063 "%s: ERROR !!!! Wireless dev is NULL", __func__);
8064 return -EINVAL;
8065 }
8066 goto done;
8067 }
8068
8069 default:
8070 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8071 __func__);
8072 return -EOPNOTSUPP;
8073 }
8074 }
8075 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008076 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008077 )
8078 {
8079 switch(type)
8080 {
8081 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008082 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008083 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05308084
8085 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308086#ifdef FEATURE_WLAN_TDLS
8087
8088 /* A Mutex Lock is introduced while changing the mode to
8089 * protect the concurrent access for the Adapters by TDLS
8090 * module.
8091 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308092 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308093#endif
c_hpothu002231a2015-02-05 14:58:51 +05308094 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008095 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008096 //Check for sub-string p2p to confirm its a p2p interface
8097 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008098 {
8099 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8100 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8101 }
8102 else
8103 {
8104 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008105 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008106 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008107 hdd_set_conparam(0);
8108 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008109 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
8110 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308111#ifdef FEATURE_WLAN_TDLS
8112 mutex_unlock(&pHddCtx->tdls_lock);
8113#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308114 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008115 if( VOS_STATUS_SUCCESS != status )
8116 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07008117 /* In case of JB, for P2P-GO, only change interface will be called,
8118 * This is the right place to enable back bmps_imps()
8119 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308120 if (pHddCtx->hdd_wlan_suspended)
8121 {
8122 hdd_set_pwrparams(pHddCtx);
8123 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008124 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008125 goto done;
8126 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008127 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008128 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008129 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8130 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008131 goto done;
8132 default:
8133 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8134 __func__);
8135 return -EOPNOTSUPP;
8136
8137 }
8138
8139 }
8140 else
8141 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308142 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
8143 __func__, hdd_device_modetoString(pAdapter->device_mode),
8144 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008145 return -EOPNOTSUPP;
8146 }
8147
8148
8149 if(pRoamProfile)
8150 {
8151 if ( LastBSSType != pRoamProfile->BSSType )
8152 {
8153 /*interface type changed update in wiphy structure*/
8154 wdev->iftype = type;
8155
8156 /*the BSS mode changed, We need to issue disconnect
8157 if connected or in IBSS disconnect state*/
8158 if ( hdd_connGetConnectedBssType(
8159 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
8160 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
8161 {
8162 /*need to issue a disconnect to CSR.*/
8163 INIT_COMPLETION(pAdapter->disconnect_comp_var);
8164 if( eHAL_STATUS_SUCCESS ==
8165 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
8166 pAdapter->sessionId,
8167 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
8168 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308169 ret = wait_for_completion_interruptible_timeout(
8170 &pAdapter->disconnect_comp_var,
8171 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
8172 if (ret <= 0)
8173 {
8174 hddLog(VOS_TRACE_LEVEL_ERROR,
8175 FL("wait on disconnect_comp_var failed %ld"), ret);
8176 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008177 }
8178 }
8179 }
8180 }
8181
8182done:
8183 /*set bitmask based on updated value*/
8184 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07008185
8186 /* Only STA mode support TM now
8187 * all other mode, TM feature should be disabled */
8188 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
8189 (~VOS_STA & pHddCtx->concurrency_mode) )
8190 {
8191 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
8192 }
8193
Jeff Johnson295189b2012-06-20 16:38:30 -07008194#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308195 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05308196 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07008197 {
8198 //we are ok to do AMP
8199 pHddCtx->isAmpAllowed = VOS_TRUE;
8200 }
8201#endif //WLAN_BTAMP_FEATURE
8202 EXIT();
8203 return 0;
8204}
8205
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308206/*
8207 * FUNCTION: wlan_hdd_cfg80211_change_iface
8208 * wrapper function to protect the actual implementation from SSR.
8209 */
8210int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
8211 struct net_device *ndev,
8212 enum nl80211_iftype type,
8213 u32 *flags,
8214 struct vif_params *params
8215 )
8216{
8217 int ret;
8218
8219 vos_ssr_protect(__func__);
8220 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
8221 vos_ssr_unprotect(__func__);
8222
8223 return ret;
8224}
8225
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008226#ifdef FEATURE_WLAN_TDLS
8227static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
8228 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
8229{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008230 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008231 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308232 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308233 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308234 hdd_adapter_t *pAdapter;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008235
8236 ENTER();
8237
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308238 if (!dev) {
8239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
8240 return -EINVAL;
8241 }
8242
8243 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8244 if (!pAdapter) {
8245 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
8246 return -EINVAL;
8247 }
8248
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308249 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008250 {
8251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8252 "Invalid arguments");
8253 return -EINVAL;
8254 }
Hoonki Lee27511902013-03-14 18:19:06 -07008255
8256 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
8257 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
8258 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07008260 "%s: TDLS mode is disabled OR not enabled in FW."
8261 MAC_ADDRESS_STR " Request declined.",
8262 __func__, MAC_ADDR_ARRAY(mac));
8263 return -ENOTSUPP;
8264 }
8265
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008266 if (pHddCtx->isLogpInProgress)
8267 {
8268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8269 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05308270 wlan_hdd_tdls_set_link_status(pAdapter,
8271 mac,
8272 eTDLS_LINK_IDLE,
8273 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008274 return -EBUSY;
8275 }
8276
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05308277 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008278
8279 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008281 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
8282 __func__, MAC_ADDR_ARRAY(mac), update);
8283 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008284 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008285
8286 /* in add station, we accept existing valid staId if there is */
8287 if ((0 == update) &&
8288 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
8289 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008290 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008292 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008293 " link_status %d. staId %d. add station ignored.",
8294 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
8295 return 0;
8296 }
8297 /* in change station, we accept only when staId is valid */
8298 if ((1 == update) &&
8299 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
8300 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
8301 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308302 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008303 "%s: " MAC_ADDRESS_STR
8304 " link status %d. staId %d. change station %s.",
8305 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
8306 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
8307 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008308 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008309
8310 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05308311 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008312 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8314 "%s: " MAC_ADDRESS_STR
8315 " TDLS setup is ongoing. Request declined.",
8316 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07008317 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008318 }
8319
8320 /* first to check if we reached to maximum supported TDLS peer.
8321 TODO: for now, return -EPERM looks working fine,
8322 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308323 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8324 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008325 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8327 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308328 " TDLS Max peer already connected. Request declined."
8329 " Num of peers (%d), Max allowed (%d).",
8330 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
8331 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008332 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008333 }
8334 else
8335 {
8336 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308337 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008338 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008339 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8341 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
8342 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008343 return -EPERM;
8344 }
8345 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008346 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05308347 wlan_hdd_tdls_set_link_status(pAdapter,
8348 mac,
8349 eTDLS_LINK_CONNECTING,
8350 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008351
Jeff Johnsond75fe012013-04-06 10:53:06 -07008352 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308353 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008354 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308355 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008356 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008357 if(StaParams->htcap_present)
8358 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308359 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008360 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008362 "ht_capa->extended_capabilities: %0x",
8363 StaParams->HTCap.extendedHtCapInfo);
8364 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008366 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008368 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008369 if(StaParams->vhtcap_present)
8370 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008372 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
8373 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
8374 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
8375 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008376 {
8377 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008379 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008381 "[%d]: %x ", i, StaParams->supported_rates[i]);
8382 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07008383 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308384 else if ((1 == update) && (NULL == StaParams))
8385 {
8386 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8387 "%s : update is true, but staParams is NULL. Error!", __func__);
8388 return -EPERM;
8389 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008390
8391 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
8392
8393 if (!update)
8394 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308395 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008396 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308397 if (ret != eHAL_STATUS_SUCCESS) {
8398 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to add TDLS peer STA"));
8399 return -EPERM;
8400 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008401 }
8402 else
8403 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308404 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008405 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308406 if (ret != eHAL_STATUS_SUCCESS) {
8407 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
8408 return -EPERM;
8409 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008410 }
8411
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308412 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008413 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
8414
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308415 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008416 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308418 "%s: timeout waiting for tdls add station indication %ld",
8419 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008420 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008421 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308422
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008423 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
8424 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008426 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008427 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008428 }
8429
8430 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008431
8432error:
Atul Mittal115287b2014-07-08 13:26:33 +05308433 wlan_hdd_tdls_set_link_status(pAdapter,
8434 mac,
8435 eTDLS_LINK_IDLE,
8436 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008437 return -EPERM;
8438
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008439}
8440#endif
8441
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308442static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008443 struct net_device *dev,
8444 u8 *mac,
8445 struct station_parameters *params)
8446{
8447 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308448 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308449 hdd_context_t *pHddCtx;
8450 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008451 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308452 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008453#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008454 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008455 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308456 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008457#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008458
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308459 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308460
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308461 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308462 if ((NULL == pAdapter))
8463 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308464 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308465 "invalid adapter ");
8466 return -EINVAL;
8467 }
8468
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308469 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8470 TRACE_CODE_HDD_CHANGE_STATION,
8471 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05308472 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308473
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308474 ret = wlan_hdd_validate_context(pHddCtx);
8475 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05308476 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308477 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308478 }
8479
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308480 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8481
8482 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008483 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308484 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8485 "invalid HDD station context");
8486 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008487 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008488 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
8489
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008490 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8491 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07008492 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008493 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07008494 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308495 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07008496 WLANTL_STA_AUTHENTICATED);
8497
Gopichand Nakkala29149562013-05-10 21:43:41 +05308498 if (status != VOS_STATUS_SUCCESS)
8499 {
8500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8501 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8502 return -EINVAL;
8503 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008504 }
8505 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008506 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8507 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308508#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008509 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8510 StaParams.capability = params->capability;
8511 StaParams.uapsd_queues = params->uapsd_queues;
8512 StaParams.max_sp = params->max_sp;
8513
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308514 /* Convert (first channel , number of channels) tuple to
8515 * the total list of channels. This goes with the assumption
8516 * that if the first channel is < 14, then the next channels
8517 * are an incremental of 1 else an incremental of 4 till the number
8518 * of channels.
8519 */
8520 if (0 != params->supported_channels_len) {
8521 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8522 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8523 {
8524 int wifi_chan_index;
8525 StaParams.supported_channels[j] = params->supported_channels[i];
8526 wifi_chan_index =
8527 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8528 no_of_channels = params->supported_channels[i+1];
8529 for(k=1; k <= no_of_channels; k++)
8530 {
8531 StaParams.supported_channels[j+1] =
8532 StaParams.supported_channels[j] + wifi_chan_index;
8533 j+=1;
8534 }
8535 }
8536 StaParams.supported_channels_len = j;
8537 }
8538 vos_mem_copy(StaParams.supported_oper_classes,
8539 params->supported_oper_classes,
8540 params->supported_oper_classes_len);
8541 StaParams.supported_oper_classes_len =
8542 params->supported_oper_classes_len;
8543
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008544 if (0 != params->ext_capab_len)
8545 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8546 sizeof(StaParams.extn_capability));
8547
8548 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008549 {
8550 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008551 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008552 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008553
8554 StaParams.supported_rates_len = params->supported_rates_len;
8555
8556 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8557 * The supported_rates array , for all the structures propogating till Add Sta
8558 * to the firmware has to be modified , if the supplicant (ieee80211) is
8559 * modified to send more rates.
8560 */
8561
8562 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8563 */
8564 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8565 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8566
8567 if (0 != StaParams.supported_rates_len) {
8568 int i = 0;
8569 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8570 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008572 "Supported Rates with Length %d", StaParams.supported_rates_len);
8573 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008575 "[%d]: %0x", i, StaParams.supported_rates[i]);
8576 }
8577
8578 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008579 {
8580 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008581 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008582 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008583
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008584 if (0 != params->ext_capab_len ) {
8585 /*Define A Macro : TODO Sunil*/
8586 if ((1<<4) & StaParams.extn_capability[3]) {
8587 isBufSta = 1;
8588 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308589 /* TDLS Channel Switching Support */
8590 if ((1<<6) & StaParams.extn_capability[3]) {
8591 isOffChannelSupported = 1;
8592 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008593 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308594 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8595 &StaParams, isBufSta,
8596 isOffChannelSupported);
8597
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308598 if (VOS_STATUS_SUCCESS != status) {
8599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8600 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8601 return -EINVAL;
8602 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008603 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8604
8605 if (VOS_STATUS_SUCCESS != status) {
8606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8607 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8608 return -EINVAL;
8609 }
8610 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008611#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308612 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008613 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008614 return status;
8615}
8616
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308617static int wlan_hdd_change_station(struct wiphy *wiphy,
8618 struct net_device *dev,
8619 u8 *mac,
8620 struct station_parameters *params)
8621{
8622 int ret;
8623
8624 vos_ssr_protect(__func__);
8625 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
8626 vos_ssr_unprotect(__func__);
8627
8628 return ret;
8629}
8630
Jeff Johnson295189b2012-06-20 16:38:30 -07008631/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308632 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008633 * This function is used to initialize the key information
8634 */
8635#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308636static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008637 struct net_device *ndev,
8638 u8 key_index, bool pairwise,
8639 const u8 *mac_addr,
8640 struct key_params *params
8641 )
8642#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308643static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008644 struct net_device *ndev,
8645 u8 key_index, const u8 *mac_addr,
8646 struct key_params *params
8647 )
8648#endif
8649{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008650 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07008651 tCsrRoamSetKey setKey;
8652 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308653 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008654 v_U32_t roamId= 0xFF;
8655 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008656 hdd_hostapd_state_t *pHostapdState;
8657 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008658 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308659 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008660
8661 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308662
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308663 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8664 TRACE_CODE_HDD_CFG80211_ADD_KEY,
8665 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308666 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8667 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308668 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008669 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308670 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008671 }
8672
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308673 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8674 __func__, hdd_device_modetoString(pAdapter->device_mode),
8675 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008676
8677 if (CSR_MAX_NUM_KEY <= key_index)
8678 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008679 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008680 key_index);
8681
8682 return -EINVAL;
8683 }
8684
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008685 if (CSR_MAX_KEY_LEN < params->key_len)
8686 {
8687 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
8688 params->key_len);
8689
8690 return -EINVAL;
8691 }
8692
8693 hddLog(VOS_TRACE_LEVEL_INFO,
8694 "%s: called with key index = %d & key length %d",
8695 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008696
8697 /*extract key idx, key len and key*/
8698 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8699 setKey.keyId = key_index;
8700 setKey.keyLength = params->key_len;
8701 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
8702
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008703 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07008704 {
8705 case WLAN_CIPHER_SUITE_WEP40:
8706 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
8707 break;
8708
8709 case WLAN_CIPHER_SUITE_WEP104:
8710 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
8711 break;
8712
8713 case WLAN_CIPHER_SUITE_TKIP:
8714 {
8715 u8 *pKey = &setKey.Key[0];
8716 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
8717
8718 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
8719
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008720 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07008721
8722 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008723 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008724 |--------------|----------|----------|
8725 <---16bytes---><--8bytes--><--8bytes-->
8726
8727 */
8728 /*Sme expects the 32 bytes key to be in the below order
8729
8730 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008731 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008732 |--------------|----------|----------|
8733 <---16bytes---><--8bytes--><--8bytes-->
8734 */
8735 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008736 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07008737
8738 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008739 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008740
8741 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008742 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008743
8744
8745 break;
8746 }
8747
8748 case WLAN_CIPHER_SUITE_CCMP:
8749 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
8750 break;
8751
8752#ifdef FEATURE_WLAN_WAPI
8753 case WLAN_CIPHER_SUITE_SMS4:
8754 {
8755 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8756 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
8757 params->key, params->key_len);
8758 return 0;
8759 }
8760#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008761
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008762#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07008763 case WLAN_CIPHER_SUITE_KRK:
8764 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
8765 break;
8766#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008767
8768#ifdef WLAN_FEATURE_11W
8769 case WLAN_CIPHER_SUITE_AES_CMAC:
8770 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07008771 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07008772#endif
8773
Jeff Johnson295189b2012-06-20 16:38:30 -07008774 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008775 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07008776 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308777 status = -EOPNOTSUPP;
8778 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008779 }
8780
8781 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
8782 __func__, setKey.encType);
8783
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008784 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07008785#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8786 (!pairwise)
8787#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008788 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07008789#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008790 )
8791 {
8792 /* set group key*/
8793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8794 "%s- %d: setting Broadcast key",
8795 __func__, __LINE__);
8796 setKey.keyDirection = eSIR_RX_ONLY;
8797 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8798 }
8799 else
8800 {
8801 /* set pairwise key*/
8802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8803 "%s- %d: setting pairwise key",
8804 __func__, __LINE__);
8805 setKey.keyDirection = eSIR_TX_RX;
8806 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8807 }
8808 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
8809 {
8810 setKey.keyDirection = eSIR_TX_RX;
8811 /*Set the group key*/
8812 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8813 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07008814
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008815 if ( 0 != status )
8816 {
8817 hddLog(VOS_TRACE_LEVEL_ERROR,
8818 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308819 status = -EINVAL;
8820 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008821 }
8822 /*Save the keys here and call sme_RoamSetKey for setting
8823 the PTK after peer joins the IBSS network*/
8824 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
8825 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308826 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008827 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05308828 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
8829 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
8830 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008831 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008832 if( pHostapdState->bssState == BSS_START )
8833 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008834 status = WLANSAP_SetKeySta( pVosContext, &setKey);
8835
8836 if ( status != eHAL_STATUS_SUCCESS )
8837 {
8838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8839 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8840 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308841 status = -EINVAL;
8842 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008843 }
8844 }
8845
8846 /* Saving WEP keys */
8847 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
8848 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
8849 {
8850 //Save the wep key in ap context. Issue setkey after the BSS is started.
8851 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8852 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
8853 }
8854 else
8855 {
8856 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008857 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008858 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
8859 }
8860 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008861 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
8862 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008863 {
8864 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8865 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8866
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308867#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8868 if (!pairwise)
8869#else
8870 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8871#endif
8872 {
8873 /* set group key*/
8874 if (pHddStaCtx->roam_info.deferKeyComplete)
8875 {
8876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8877 "%s- %d: Perform Set key Complete",
8878 __func__, __LINE__);
8879 hdd_PerformRoamSetKeyComplete(pAdapter);
8880 }
8881 }
8882
Jeff Johnson295189b2012-06-20 16:38:30 -07008883 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
8884
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08008885 pWextState->roamProfile.Keys.defaultIndex = key_index;
8886
8887
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008888 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008889 params->key, params->key_len);
8890
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308891
Jeff Johnson295189b2012-06-20 16:38:30 -07008892 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8893
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308894 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008895 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308896 __func__, setKey.peerMac[0], setKey.peerMac[1],
8897 setKey.peerMac[2], setKey.peerMac[3],
8898 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008899 setKey.keyDirection);
8900
Nirav Shah4f765af2015-01-21 19:51:30 +05308901 /* Wait for EAPOL M4 before setting key.
8902 * No need to consider Dynamic WEP as we will receive M8.
8903 */
8904 if ( (setKey.encType == eCSR_ENCRYPT_TYPE_AES ||
8905 setKey.encType == eCSR_ENCRYPT_TYPE_TKIP) &&
8906 ( 1
8907#if defined WLAN_FEATURE_VOWIFI_11R
8908 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN
8909 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN_PSK
8910#endif
8911#ifdef FEATURE_WLAN_ESE
8912 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_WPA
8913 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_RSN
8914#endif
8915 ))
Jeff Johnson295189b2012-06-20 16:38:30 -07008916 {
Nirav Shah4f765af2015-01-21 19:51:30 +05308917 vos_status = wlan_hdd_check_ula_done(pAdapter);
8918
8919 if ( vos_status != VOS_STATUS_SUCCESS )
8920 {
8921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008922 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8923 __LINE__, vos_status );
8924
Nirav Shah4f765af2015-01-21 19:51:30 +05308925 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008926
Nirav Shah4f765af2015-01-21 19:51:30 +05308927 status = -EINVAL;
8928 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008929
Nirav Shah4f765af2015-01-21 19:51:30 +05308930 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008931 }
8932
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008933#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308934 /* The supplicant may attempt to set the PTK once pre-authentication
8935 is done. Save the key in the UMAC and include it in the ADD BSS
8936 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008937 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308938 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008939 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308940 hddLog(VOS_TRACE_LEVEL_INFO_MED,
8941 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308942 status = 0;
8943 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308944 }
8945 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
8946 {
8947 hddLog(VOS_TRACE_LEVEL_ERROR,
8948 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308949 status = -EINVAL;
8950 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008951 }
8952#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07008953
8954 /* issue set key request to SME*/
8955 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8956 pAdapter->sessionId, &setKey, &roamId );
8957
8958 if ( 0 != status )
8959 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308960 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008961 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
8962 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308963 status = -EINVAL;
8964 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008965 }
8966
8967
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308968 /* in case of IBSS as there was no information available about WEP keys during
8969 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07008970 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308971 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
8972 !( ( IW_AUTH_KEY_MGMT_802_1X
8973 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07008974 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
8975 )
8976 &&
8977 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
8978 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
8979 )
8980 )
8981 {
8982 setKey.keyDirection = eSIR_RX_ONLY;
8983 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8984
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308985 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008986 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308987 __func__, setKey.peerMac[0], setKey.peerMac[1],
8988 setKey.peerMac[2], setKey.peerMac[3],
8989 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008990 setKey.keyDirection);
8991
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308992 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008993 pAdapter->sessionId, &setKey, &roamId );
8994
8995 if ( 0 != status )
8996 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308997 hddLog(VOS_TRACE_LEVEL_ERROR,
8998 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008999 __func__, status);
9000 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309001 status = -EINVAL;
9002 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009003 }
9004 }
9005 }
9006
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309007end:
9008 /* Need to clear any trace of key value in the memory.
9009 * Thus zero out the memory even though it is local
9010 * variable.
9011 */
9012 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309013 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309014 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009015}
9016
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309017#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9018static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9019 struct net_device *ndev,
9020 u8 key_index, bool pairwise,
9021 const u8 *mac_addr,
9022 struct key_params *params
9023 )
9024#else
9025static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9026 struct net_device *ndev,
9027 u8 key_index, const u8 *mac_addr,
9028 struct key_params *params
9029 )
9030#endif
9031{
9032 int ret;
9033 vos_ssr_protect(__func__);
9034#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9035 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
9036 mac_addr, params);
9037#else
9038 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
9039 params);
9040#endif
9041 vos_ssr_unprotect(__func__);
9042
9043 return ret;
9044}
9045
Jeff Johnson295189b2012-06-20 16:38:30 -07009046/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309047 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009048 * This function is used to get the key information
9049 */
9050#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309051static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309052 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009053 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309054 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009055 const u8 *mac_addr, void *cookie,
9056 void (*callback)(void *cookie, struct key_params*)
9057 )
9058#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309059static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309060 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009061 struct net_device *ndev,
9062 u8 key_index, const u8 *mac_addr, void *cookie,
9063 void (*callback)(void *cookie, struct key_params*)
9064 )
9065#endif
9066{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309067 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309068 hdd_wext_state_t *pWextState = NULL;
9069 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009070 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309071 hdd_context_t *pHddCtx;
9072 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009073
9074 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309075
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309076 if (NULL == pAdapter)
9077 {
9078 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9079 "%s: HDD adapter is Null", __func__);
9080 return -ENODEV;
9081 }
9082
9083 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9084 ret = wlan_hdd_validate_context(pHddCtx);
9085 if (0 != ret)
9086 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309087 return ret;
9088 }
9089
9090 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9091 pRoamProfile = &(pWextState->roamProfile);
9092
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309093 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9094 __func__, hdd_device_modetoString(pAdapter->device_mode),
9095 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309096
Jeff Johnson295189b2012-06-20 16:38:30 -07009097 memset(&params, 0, sizeof(params));
9098
9099 if (CSR_MAX_NUM_KEY <= key_index)
9100 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07009102 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309103 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009104
9105 switch(pRoamProfile->EncryptionType.encryptionType[0])
9106 {
9107 case eCSR_ENCRYPT_TYPE_NONE:
9108 params.cipher = IW_AUTH_CIPHER_NONE;
9109 break;
9110
9111 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
9112 case eCSR_ENCRYPT_TYPE_WEP40:
9113 params.cipher = WLAN_CIPHER_SUITE_WEP40;
9114 break;
9115
9116 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
9117 case eCSR_ENCRYPT_TYPE_WEP104:
9118 params.cipher = WLAN_CIPHER_SUITE_WEP104;
9119 break;
9120
9121 case eCSR_ENCRYPT_TYPE_TKIP:
9122 params.cipher = WLAN_CIPHER_SUITE_TKIP;
9123 break;
9124
9125 case eCSR_ENCRYPT_TYPE_AES:
9126 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
9127 break;
9128
9129 default:
9130 params.cipher = IW_AUTH_CIPHER_NONE;
9131 break;
9132 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309133
c_hpothuaaf19692014-05-17 17:01:48 +05309134 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9135 TRACE_CODE_HDD_CFG80211_GET_KEY,
9136 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309137
Jeff Johnson295189b2012-06-20 16:38:30 -07009138 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
9139 params.seq_len = 0;
9140 params.seq = NULL;
9141 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
9142 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309143 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009144 return 0;
9145}
9146
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309147#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9148static int wlan_hdd_cfg80211_get_key(
9149 struct wiphy *wiphy,
9150 struct net_device *ndev,
9151 u8 key_index, bool pairwise,
9152 const u8 *mac_addr, void *cookie,
9153 void (*callback)(void *cookie, struct key_params*)
9154 )
9155#else
9156static int wlan_hdd_cfg80211_get_key(
9157 struct wiphy *wiphy,
9158 struct net_device *ndev,
9159 u8 key_index, const u8 *mac_addr, void *cookie,
9160 void (*callback)(void *cookie, struct key_params*)
9161 )
9162#endif
9163{
9164 int ret;
9165
9166 vos_ssr_protect(__func__);
9167#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9168 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
9169 mac_addr, cookie, callback);
9170#else
9171 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
9172 callback);
9173#endif
9174 vos_ssr_unprotect(__func__);
9175
9176 return ret;
9177}
9178
Jeff Johnson295189b2012-06-20 16:38:30 -07009179/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309180 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009181 * This function is used to delete the key information
9182 */
9183#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309184static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009185 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309186 u8 key_index,
9187 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009188 const u8 *mac_addr
9189 )
9190#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309191static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009192 struct net_device *ndev,
9193 u8 key_index,
9194 const u8 *mac_addr
9195 )
9196#endif
9197{
9198 int status = 0;
9199
9200 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309201 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009202 //it is observed that this is invalidating peer
9203 //key index whenever re-key is done. This is affecting data link.
9204 //It should be ok to ignore del_key.
9205#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309206 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
9207 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009208 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
9209 tCsrRoamSetKey setKey;
9210 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309211
Jeff Johnson295189b2012-06-20 16:38:30 -07009212 ENTER();
9213
9214 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
9215 __func__,pAdapter->device_mode);
9216
9217 if (CSR_MAX_NUM_KEY <= key_index)
9218 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309219 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009220 key_index);
9221
9222 return -EINVAL;
9223 }
9224
9225 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9226 setKey.keyId = key_index;
9227
9228 if (mac_addr)
9229 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9230 else
9231 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
9232
9233 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
9234
9235 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009236 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309237 )
9238 {
9239
9240 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07009241 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9242 if( pHostapdState->bssState == BSS_START)
9243 {
9244 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309245
Jeff Johnson295189b2012-06-20 16:38:30 -07009246 if ( status != eHAL_STATUS_SUCCESS )
9247 {
9248 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9249 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9250 __LINE__, status );
9251 }
9252 }
9253 }
9254 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309255 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07009256 )
9257 {
9258 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9259
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309260 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9261
9262 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009263 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309264 __func__, setKey.peerMac[0], setKey.peerMac[1],
9265 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07009266 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309267 if(pAdapter->sessionCtx.station.conn_info.connState ==
9268 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07009269 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309270 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009271 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309272
Jeff Johnson295189b2012-06-20 16:38:30 -07009273 if ( 0 != status )
9274 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309275 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009276 "%s: sme_RoamSetKey failure, returned %d",
9277 __func__, status);
9278 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9279 return -EINVAL;
9280 }
9281 }
9282 }
9283#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009284 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009285 return status;
9286}
9287
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309288#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9289static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9290 struct net_device *ndev,
9291 u8 key_index,
9292 bool pairwise,
9293 const u8 *mac_addr
9294 )
9295#else
9296static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9297 struct net_device *ndev,
9298 u8 key_index,
9299 const u8 *mac_addr
9300 )
9301#endif
9302{
9303 int ret;
9304
9305 vos_ssr_protect(__func__);
9306#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9307 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
9308 mac_addr);
9309#else
9310 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
9311#endif
9312 vos_ssr_unprotect(__func__);
9313
9314 return ret;
9315}
9316
Jeff Johnson295189b2012-06-20 16:38:30 -07009317/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309318 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009319 * This function is used to set the default tx key index
9320 */
9321#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309322static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009323 struct net_device *ndev,
9324 u8 key_index,
9325 bool unicast, bool multicast)
9326#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309327static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009328 struct net_device *ndev,
9329 u8 key_index)
9330#endif
9331{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309332 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309333 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309334 hdd_wext_state_t *pWextState;
9335 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309336 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009337
9338 ENTER();
9339
Gopichand Nakkala29149562013-05-10 21:43:41 +05309340 if ((NULL == pAdapter))
9341 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309343 "invalid adapter");
9344 return -EINVAL;
9345 }
9346
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309347 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9348 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
9349 pAdapter->sessionId, key_index));
9350
Gopichand Nakkala29149562013-05-10 21:43:41 +05309351 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9352 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9353
9354 if ((NULL == pWextState) || (NULL == pHddStaCtx))
9355 {
9356 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9357 "invalid Wext state or HDD context");
9358 return -EINVAL;
9359 }
9360
Arif Hussain6d2a3322013-11-17 19:50:10 -08009361 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009362 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309363
Jeff Johnson295189b2012-06-20 16:38:30 -07009364 if (CSR_MAX_NUM_KEY <= key_index)
9365 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309366 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009367 key_index);
9368
9369 return -EINVAL;
9370 }
9371
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309372 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9373 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309374 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009375 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309376 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009377 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309378
Jeff Johnson295189b2012-06-20 16:38:30 -07009379 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07009380 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309381 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009382 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309383 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08009384 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309385 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08009386 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07009387 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309388 {
9389 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07009390 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309391
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 tCsrRoamSetKey setKey;
9393 v_U32_t roamId= 0xFF;
9394 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309395
9396 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009397 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309398
Jeff Johnson295189b2012-06-20 16:38:30 -07009399 Keys->defaultIndex = (u8)key_index;
9400 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9401 setKey.keyId = key_index;
9402 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309403
9404 vos_mem_copy(&setKey.Key[0],
9405 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009406 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309407
Gopichand Nakkala29149562013-05-10 21:43:41 +05309408 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309409
9410 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07009411 &pHddStaCtx->conn_info.bssId[0],
9412 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309413
Gopichand Nakkala29149562013-05-10 21:43:41 +05309414 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
9415 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
9416 eCSR_ENCRYPT_TYPE_WEP104)
9417 {
9418 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
9419 even though ap is configured for WEP-40 encryption. In this canse the key length
9420 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
9421 type(104) and switching encryption type to 40*/
9422 pWextState->roamProfile.EncryptionType.encryptionType[0] =
9423 eCSR_ENCRYPT_TYPE_WEP40;
9424 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
9425 eCSR_ENCRYPT_TYPE_WEP40;
9426 }
9427
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309428 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07009429 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309430
Jeff Johnson295189b2012-06-20 16:38:30 -07009431 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309432 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009433 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309434
Jeff Johnson295189b2012-06-20 16:38:30 -07009435 if ( 0 != status )
9436 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309437 hddLog(VOS_TRACE_LEVEL_ERROR,
9438 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009439 status);
9440 return -EINVAL;
9441 }
9442 }
9443 }
9444
9445 /* In SoftAp mode setting key direction for default mode */
9446 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
9447 {
9448 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
9449 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
9450 (eCSR_ENCRYPT_TYPE_AES !=
9451 pWextState->roamProfile.EncryptionType.encryptionType[0])
9452 )
9453 {
9454 /* Saving key direction for default key index to TX default */
9455 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9456 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
9457 }
9458 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309459 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009460 return status;
9461}
9462
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309463#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9464static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9465 struct net_device *ndev,
9466 u8 key_index,
9467 bool unicast, bool multicast)
9468#else
9469static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9470 struct net_device *ndev,
9471 u8 key_index)
9472#endif
9473{
9474 int ret;
9475 vos_ssr_protect(__func__);
9476#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9477 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
9478 multicast);
9479#else
9480 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
9481#endif
9482 vos_ssr_unprotect(__func__);
9483
9484 return ret;
9485}
9486
Jeff Johnson295189b2012-06-20 16:38:30 -07009487/*
9488 * FUNCTION: wlan_hdd_cfg80211_inform_bss
9489 * This function is used to inform the BSS details to nl80211 interface.
9490 */
9491static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
9492 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
9493{
9494 struct net_device *dev = pAdapter->dev;
9495 struct wireless_dev *wdev = dev->ieee80211_ptr;
9496 struct wiphy *wiphy = wdev->wiphy;
9497 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
9498 int chan_no;
9499 int ie_length;
9500 const char *ie;
9501 unsigned int freq;
9502 struct ieee80211_channel *chan;
9503 int rssi = 0;
9504 struct cfg80211_bss *bss = NULL;
9505
9506 ENTER();
9507
9508 if( NULL == pBssDesc )
9509 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009510 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009511 return bss;
9512 }
9513
9514 chan_no = pBssDesc->channelId;
9515 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
9516 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
9517
9518 if( NULL == ie )
9519 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009520 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009521 return bss;
9522 }
9523
9524#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9525 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9526 {
9527 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9528 }
9529 else
9530 {
9531 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9532 }
9533#else
9534 freq = ieee80211_channel_to_frequency(chan_no);
9535#endif
9536
9537 chan = __ieee80211_get_channel(wiphy, freq);
9538
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05309539 if (!chan) {
9540 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
9541 return NULL;
9542 }
9543
Abhishek Singhaee43942014-06-16 18:55:47 +05309544 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07009545
Abhishek Singhaee43942014-06-16 18:55:47 +05309546 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309547 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07009548 pBssDesc->capabilityInfo,
9549 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05309550 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07009551}
9552
9553
9554
9555/*
9556 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
9557 * This function is used to inform the BSS details to nl80211 interface.
9558 */
9559struct cfg80211_bss*
9560wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9561 tSirBssDescription *bss_desc
9562 )
9563{
9564 /*
9565 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9566 already exists in bss data base of cfg80211 for that particular BSS ID.
9567 Using cfg80211_inform_bss_frame to update the bss entry instead of
9568 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9569 now there is no possibility to get the mgmt(probe response) frame from PE,
9570 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9571 cfg80211_inform_bss_frame.
9572 */
9573 struct net_device *dev = pAdapter->dev;
9574 struct wireless_dev *wdev = dev->ieee80211_ptr;
9575 struct wiphy *wiphy = wdev->wiphy;
9576 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009577#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9578 qcom_ie_age *qie_age = NULL;
9579 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9580#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009581 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009582#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009583 const char *ie =
9584 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9585 unsigned int freq;
9586 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309587 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 struct cfg80211_bss *bss_status = NULL;
9589 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9590 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009591 hdd_context_t *pHddCtx;
9592 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009593#ifdef WLAN_OPEN_SOURCE
9594 struct timespec ts;
9595#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009596
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309597 ENTER();
9598
Wilson Yangf80a0542013-10-07 13:02:37 -07009599 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9600 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -07009601 if (0 != status)
9602 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009603 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009604 }
9605
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309606 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009607 if (!mgmt)
9608 {
9609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9610 "%s: memory allocation failed ", __func__);
9611 return NULL;
9612 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009613
Jeff Johnson295189b2012-06-20 16:38:30 -07009614 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07009615
9616#ifdef WLAN_OPEN_SOURCE
9617 /* Android does not want the timestamp from the frame.
9618 Instead it wants a monotonic increasing value */
9619 get_monotonic_boottime(&ts);
9620 mgmt->u.probe_resp.timestamp =
9621 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
9622#else
9623 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009624 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
9625 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07009626
9627#endif
9628
Jeff Johnson295189b2012-06-20 16:38:30 -07009629 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
9630 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009631
9632#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9633 /* GPS Requirement: need age ie per entry. Using vendor specific. */
9634 /* Assuming this is the last IE, copy at the end */
9635 ie_length -=sizeof(qcom_ie_age);
9636 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
9637 qie_age->element_id = QCOM_VENDOR_IE_ID;
9638 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
9639 qie_age->oui_1 = QCOM_OUI1;
9640 qie_age->oui_2 = QCOM_OUI2;
9641 qie_age->oui_3 = QCOM_OUI3;
9642 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
9643 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
9644#endif
9645
Jeff Johnson295189b2012-06-20 16:38:30 -07009646 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05309647 if (bss_desc->fProbeRsp)
9648 {
9649 mgmt->frame_control |=
9650 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
9651 }
9652 else
9653 {
9654 mgmt->frame_control |=
9655 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
9656 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009657
9658#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309659 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009660 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
9661 {
9662 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9663 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309664 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009665 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
9666
9667 {
9668 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9669 }
9670 else
9671 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309672 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
9673 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07009674 kfree(mgmt);
9675 return NULL;
9676 }
9677#else
9678 freq = ieee80211_channel_to_frequency(chan_no);
9679#endif
9680 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009681 /*when the band is changed on the fly using the GUI, three things are done
9682 * 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)
9683 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
9684 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
9685 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
9686 * and discards the channels correponding to previous band and calls back with zero bss results.
9687 * 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
9688 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
9689 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
9690 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
9691 * So drop the bss and continue to next bss.
9692 */
9693 if(chan == NULL)
9694 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07009696 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009697 return NULL;
9698 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009699 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309700 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07009701 * */
9702 if (( eConnectionState_Associated ==
9703 pAdapter->sessionCtx.station.conn_info.connState ) &&
9704 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
9705 pAdapter->sessionCtx.station.conn_info.bssId,
9706 WNI_CFG_BSSID_LEN)))
9707 {
9708 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
9709 rssi = (pAdapter->rssi * 100);
9710 }
9711 else
9712 {
9713 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
9714 }
9715
Nirav Shah20ac06f2013-12-12 18:14:06 +05309716 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
9717 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
9718 chan->center_freq, (int)(rssi/100));
9719
Jeff Johnson295189b2012-06-20 16:38:30 -07009720 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
9721 frame_len, rssi, GFP_KERNEL);
9722 kfree(mgmt);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309723 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009724 return bss_status;
9725}
9726
9727/*
9728 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
9729 * This function is used to update the BSS data base of CFG8011
9730 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309731struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009732 tCsrRoamInfo *pRoamInfo
9733 )
9734{
9735 tCsrRoamConnectedProfile roamProfile;
9736 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9737 struct cfg80211_bss *bss = NULL;
9738
9739 ENTER();
9740
9741 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
9742 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
9743
9744 if (NULL != roamProfile.pBssDesc)
9745 {
Girish Gowlif4b68022014-08-28 23:18:57 +05309746 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9747 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009748
9749 if (NULL == bss)
9750 {
9751 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
9752 __func__);
9753 }
9754
9755 sme_RoamFreeConnectProfile(hHal, &roamProfile);
9756 }
9757 else
9758 {
9759 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
9760 __func__);
9761 }
9762 return bss;
9763}
9764
9765/*
9766 * FUNCTION: wlan_hdd_cfg80211_update_bss
9767 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309768static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
9769 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07009770 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309771{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309772 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009773 tCsrScanResultInfo *pScanResult;
9774 eHalStatus status = 0;
9775 tScanResultHandle pResult;
9776 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009777 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009778
9779 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309780
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309781 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9782 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
9783 NO_SESSION, pAdapter->sessionId));
9784
Wilson Yangf80a0542013-10-07 13:02:37 -07009785 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9786
9787 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009788 {
Wilson Yangf80a0542013-10-07 13:02:37 -07009789 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9790 "%s:LOGP in Progress. Ignore!!!",__func__);
9791 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009792 }
9793
Wilson Yangf80a0542013-10-07 13:02:37 -07009794
9795 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309796 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009797 {
9798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9799 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9800 return VOS_STATUS_E_PERM;
9801 }
9802
9803
Jeff Johnson295189b2012-06-20 16:38:30 -07009804 /*
9805 * start getting scan results and populate cgf80211 BSS database
9806 */
9807 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
9808
9809 /* no scan results */
9810 if (NULL == pResult)
9811 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309812 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
9813 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009814 return status;
9815 }
9816
9817 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
9818
9819 while (pScanResult)
9820 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309821 /*
9822 * cfg80211_inform_bss() is not updating ie field of bss entry, if
9823 * entry already exists in bss data base of cfg80211 for that
9824 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
9825 * bss entry instead of cfg80211_inform_bss, But this call expects
9826 * mgmt packet as input. As of now there is no possibility to get
9827 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07009828 * ieee80211_mgmt(probe response) and passing to c
9829 * fg80211_inform_bss_frame.
9830 * */
9831
9832 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9833 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309834
Jeff Johnson295189b2012-06-20 16:38:30 -07009835
9836 if (NULL == bss_status)
9837 {
9838 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009839 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009840 }
9841 else
9842 {
Yue Maf49ba872013-08-19 12:04:25 -07009843 cfg80211_put_bss(
9844#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
9845 wiphy,
9846#endif
9847 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009848 }
9849
9850 pScanResult = sme_ScanResultGetNext(hHal, pResult);
9851 }
9852
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309853 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07009854
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309855 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009856}
9857
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009858void
9859hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
9860{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309861 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08009862 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009863} /****** end hddPrintMacAddr() ******/
9864
9865void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009866hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009867{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309868 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009869 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009870 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
9871 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
9872 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009873} /****** end hddPrintPmkId() ******/
9874
9875//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
9876//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
9877
9878//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
9879//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
9880
9881#define dump_bssid(bssid) \
9882 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009883 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
9884 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009885 }
9886
9887#define dump_pmkid(pMac, pmkid) \
9888 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009889 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
9890 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009891 }
9892
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009893#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009894/*
9895 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
9896 * This function is used to notify the supplicant of a new PMKSA candidate.
9897 */
9898int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309899 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009900 int index, bool preauth )
9901{
Jeff Johnsone7245742012-09-05 17:12:55 -07009902#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009903 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009904 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009905
9906 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07009907 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009908
9909 if( NULL == pRoamInfo )
9910 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009911 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009912 return -EINVAL;
9913 }
9914
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009915 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
9916 {
9917 dump_bssid(pRoamInfo->bssid);
9918 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009919 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009920 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009921#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309922 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009923}
9924#endif //FEATURE_WLAN_LFR
9925
Yue Maef608272013-04-08 23:09:17 -07009926#ifdef FEATURE_WLAN_LFR_METRICS
9927/*
9928 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
9929 * 802.11r/LFR metrics reporting function to report preauth initiation
9930 *
9931 */
9932#define MAX_LFR_METRICS_EVENT_LENGTH 100
9933VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
9934 tCsrRoamInfo *pRoamInfo)
9935{
9936 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9937 union iwreq_data wrqu;
9938
9939 ENTER();
9940
9941 if (NULL == pAdapter)
9942 {
9943 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9944 return VOS_STATUS_E_FAILURE;
9945 }
9946
9947 /* create the event */
9948 memset(&wrqu, 0, sizeof(wrqu));
9949 memset(metrics_notification, 0, sizeof(metrics_notification));
9950
9951 wrqu.data.pointer = metrics_notification;
9952 wrqu.data.length = scnprintf(metrics_notification,
9953 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
9954 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9955
9956 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9957
9958 EXIT();
9959
9960 return VOS_STATUS_SUCCESS;
9961}
9962
9963/*
9964 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
9965 * 802.11r/LFR metrics reporting function to report preauth completion
9966 * or failure
9967 */
9968VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
9969 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
9970{
9971 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9972 union iwreq_data wrqu;
9973
9974 ENTER();
9975
9976 if (NULL == pAdapter)
9977 {
9978 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9979 return VOS_STATUS_E_FAILURE;
9980 }
9981
9982 /* create the event */
9983 memset(&wrqu, 0, sizeof(wrqu));
9984 memset(metrics_notification, 0, sizeof(metrics_notification));
9985
9986 scnprintf(metrics_notification, sizeof(metrics_notification),
9987 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
9988 MAC_ADDR_ARRAY(pRoamInfo->bssid));
9989
9990 if (1 == preauth_status)
9991 strncat(metrics_notification, " TRUE", 5);
9992 else
9993 strncat(metrics_notification, " FALSE", 6);
9994
9995 wrqu.data.pointer = metrics_notification;
9996 wrqu.data.length = strlen(metrics_notification);
9997
9998 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9999
10000 EXIT();
10001
10002 return VOS_STATUS_SUCCESS;
10003}
10004
10005/*
10006 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
10007 * 802.11r/LFR metrics reporting function to report handover initiation
10008 *
10009 */
10010VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
10011 tCsrRoamInfo *pRoamInfo)
10012{
10013 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10014 union iwreq_data wrqu;
10015
10016 ENTER();
10017
10018 if (NULL == pAdapter)
10019 {
10020 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10021 return VOS_STATUS_E_FAILURE;
10022 }
10023
10024 /* create the event */
10025 memset(&wrqu, 0, sizeof(wrqu));
10026 memset(metrics_notification, 0, sizeof(metrics_notification));
10027
10028 wrqu.data.pointer = metrics_notification;
10029 wrqu.data.length = scnprintf(metrics_notification,
10030 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
10031 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10032
10033 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10034
10035 EXIT();
10036
10037 return VOS_STATUS_SUCCESS;
10038}
10039#endif
10040
Jeff Johnson295189b2012-06-20 16:38:30 -070010041/*
10042 * FUNCTION: hdd_cfg80211_scan_done_callback
10043 * scanning callback function, called after finishing scan
10044 *
10045 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010046static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070010047 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
10048{
10049 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010050 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070010051 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010052 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010053 struct cfg80211_scan_request *req = NULL;
10054 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010055 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010056 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010057 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010058 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010059
10060 ENTER();
10061
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010062 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10063 if (0 != wlan_hdd_validate_context(pHddCtx)) {
10064 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
10065 goto allow_suspend;
10066 }
10067
10068 pScanInfo = &pHddCtx->scan_info;
10069
Jeff Johnson295189b2012-06-20 16:38:30 -070010070 hddLog(VOS_TRACE_LEVEL_INFO,
10071 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080010072 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010073 __func__, halHandle, pContext, (int) scanId, (int) status);
10074
Kiet Lamac06e2c2013-10-23 16:25:07 +053010075 pScanInfo->mScanPendingCounter = 0;
10076
Jeff Johnson295189b2012-06-20 16:38:30 -070010077 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010078 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010079 &pScanInfo->scan_req_completion_event,
10080 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010081 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070010082 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010083 hddLog(VOS_TRACE_LEVEL_ERROR,
10084 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070010085 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010086 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010087 }
10088
Yue Maef608272013-04-08 23:09:17 -070010089 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010090 {
10091 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010092 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010093 }
10094
10095 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010096 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070010097 {
10098 hddLog(VOS_TRACE_LEVEL_INFO,
10099 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010100 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070010101 (int) scanId);
10102 }
10103
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010104 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010105 pAdapter);
10106
10107 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010108 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010109
10110
10111 /* If any client wait scan result through WEXT
10112 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010113 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070010114 {
10115 /* The other scan request waiting for current scan finish
10116 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010117 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010118 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010119 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070010120 }
10121 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010122 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010123 {
10124 struct net_device *dev = pAdapter->dev;
10125 union iwreq_data wrqu;
10126 int we_event;
10127 char *msg;
10128
10129 memset(&wrqu, '\0', sizeof(wrqu));
10130 we_event = SIOCGIWSCAN;
10131 msg = NULL;
10132 wireless_send_event(dev, we_event, &wrqu, msg);
10133 }
10134 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010135 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010136
10137 /* Get the Scan Req */
10138 req = pAdapter->request;
10139
10140 if (!req)
10141 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010142 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010143 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010144 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010145 }
10146
Jeff Johnson295189b2012-06-20 16:38:30 -070010147 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070010148 /* Scan is no longer pending */
10149 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010150
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010151 /* last_scan_timestamp is used to decide if new scan
10152 * is needed or not on station interface. If last station
10153 * scan time and new station scan time is less then
10154 * last_scan_timestamp ; driver will return cached scan.
10155 */
10156 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
10157 {
10158 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
10159
10160 if ( req->n_channels )
10161 {
10162 for (i = 0; i < req->n_channels ; i++ )
10163 {
10164 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
10165 }
10166 /* store no of channel scanned */
10167 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
10168 }
10169
10170 }
10171
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070010172 /*
10173 * cfg80211_scan_done informing NL80211 about completion
10174 * of scanning
10175 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010176 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
10177 {
10178 aborted = true;
10179 }
10180 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080010181 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010182
Siddharth Bhal76972212014-10-15 16:22:51 +053010183 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
10184 /* Generate new random mac addr for next scan */
10185 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
10186 hdd_processSpoofMacAddrRequest(pHddCtx);
10187 }
10188
Jeff Johnsone7245742012-09-05 17:12:55 -070010189allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010190 /* release the wake lock at the end of the scan*/
10191 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -070010192
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010193 /* Acquire wakelock to handle the case where APP's tries to suspend
10194 * immediatly after the driver gets connect request(i.e after scan)
10195 * from supplicant, this result in app's is suspending and not able
10196 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010197 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010198
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010199#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010200 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010201#endif
10202
Jeff Johnson295189b2012-06-20 16:38:30 -070010203 EXIT();
10204 return 0;
10205}
10206
10207/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053010208 * FUNCTION: hdd_isConnectionInProgress
10209 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010210 *
10211 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010212v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010213{
10214 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10215 hdd_station_ctx_t *pHddStaCtx = NULL;
10216 hdd_adapter_t *pAdapter = NULL;
10217 VOS_STATUS status = 0;
10218 v_U8_t staId = 0;
10219 v_U8_t *staMac = NULL;
10220
c_hpothu9b781ba2013-12-30 20:57:45 +053010221 if (TRUE == pHddCtx->btCoexModeSet)
10222 {
10223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053010224 FL("BTCoex Mode operation in progress"));
10225 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053010226 }
10227
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010228 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10229
10230 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10231 {
10232 pAdapter = pAdapterNode->pAdapter;
10233
10234 if( pAdapter )
10235 {
10236 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010237 "%s: Adapter with device mode %s (%d) exists",
10238 __func__, hdd_device_modetoString(pAdapter->device_mode),
10239 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010240 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053010241 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10242 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
10243 (eConnectionState_Connecting ==
10244 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
10245 {
10246 hddLog(VOS_TRACE_LEVEL_ERROR,
10247 "%s: %p(%d) Connection is in progress", __func__,
10248 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10249 return VOS_TRUE;
10250 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010251 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053010252 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010253 {
10254 hddLog(VOS_TRACE_LEVEL_ERROR,
10255 "%s: %p(%d) Reassociation is in progress", __func__,
10256 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10257 return VOS_TRUE;
10258 }
10259 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010260 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10261 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010262 {
10263 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10264 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010265 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010266 {
10267 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
10268 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010269 "%s: client " MAC_ADDRESS_STR
10270 " is in the middle of WPS/EAPOL exchange.", __func__,
10271 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010272 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010273 }
10274 }
10275 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
10276 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
10277 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010278 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10279 ptSapContext pSapCtx = NULL;
10280 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10281 if(pSapCtx == NULL){
10282 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10283 FL("psapCtx is NULL"));
10284 return VOS_FALSE;
10285 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010286 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
10287 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010288 if ((pSapCtx->aStaInfo[staId].isUsed) &&
10289 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010290 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010291 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010292
10293 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010294 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
10295 "middle of WPS/EAPOL exchange.", __func__,
10296 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010297 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010298 }
10299 }
10300 }
10301 }
10302 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10303 pAdapterNode = pNext;
10304 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053010305 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010306}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010307
10308/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010309 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070010310 * this scan respond to scan trigger and update cfg80211 scan database
10311 * later, scan dump command can be used to recieve scan results
10312 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010313int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010314#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10315 struct net_device *dev,
10316#endif
10317 struct cfg80211_scan_request *request)
10318{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010319 hdd_adapter_t *pAdapter = NULL;
10320 hdd_context_t *pHddCtx = NULL;
10321 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010322 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010323 tCsrScanRequest scanRequest;
10324 tANI_U8 *channelList = NULL, i;
10325 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010326 int status;
10327 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010328 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010329 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010330
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010331#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
10332 struct net_device *dev = NULL;
10333 if (NULL == request)
10334 {
10335 hddLog(VOS_TRACE_LEVEL_ERROR,
10336 "%s: scan req param null", __func__);
10337 return -EINVAL;
10338 }
10339 dev = request->wdev->netdev;
10340#endif
10341
10342 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
10343 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
10344 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10345
Jeff Johnson295189b2012-06-20 16:38:30 -070010346 ENTER();
10347
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010348 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10349 __func__, hdd_device_modetoString(pAdapter->device_mode),
10350 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010351
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010352 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010353 if (0 != status)
10354 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010355 return status;
10356 }
10357
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010358 if (NULL == pwextBuf)
10359 {
10360 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
10361 __func__);
10362 return -EIO;
10363 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010364 cfg_param = pHddCtx->cfg_ini;
10365 pScanInfo = &pHddCtx->scan_info;
10366
Jeff Johnson295189b2012-06-20 16:38:30 -070010367#ifdef WLAN_BTAMP_FEATURE
10368 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010369 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070010370 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010371 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010372 "%s: No scanning when AMP is on", __func__);
10373 return -EOPNOTSUPP;
10374 }
10375#endif
10376 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010377 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010378 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010379 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010380 "%s: Not scanning on device_mode = %s (%d)",
10381 __func__, hdd_device_modetoString(pAdapter->device_mode),
10382 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010383 return -EOPNOTSUPP;
10384 }
10385
10386 if (TRUE == pScanInfo->mScanPending)
10387 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010388 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
10389 {
10390 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
10391 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010392 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010393 }
10394
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010395 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070010396 //Channel and action frame is pending
10397 //Otherwise Cancel Remain On Channel and allow Scan
10398 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010399 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070010400 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010401 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010402 return -EBUSY;
10403 }
10404
Jeff Johnson295189b2012-06-20 16:38:30 -070010405 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
10406 {
10407 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080010408 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010409 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010410 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010411 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
10412 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010413 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010414 "%s: MAX TM Level Scan not allowed", __func__);
10415 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010416 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010417 }
10418 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
10419
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010420 /* Check if scan is allowed at this point of time.
10421 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010422 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010423 {
10424 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
10425 return -EBUSY;
10426 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010427
Jeff Johnson295189b2012-06-20 16:38:30 -070010428 vos_mem_zero( &scanRequest, sizeof(scanRequest));
10429
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010430 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
10431 (int)request->n_ssids);
10432
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010433
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010434 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
10435 * Becasue of this, driver is assuming that this is not wildcard scan and so
10436 * is not aging out the scan results.
10437 */
10438 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010439 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010440 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010441 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010442
10443 if ((request->ssids) && (0 < request->n_ssids))
10444 {
10445 tCsrSSIDInfo *SsidInfo;
10446 int j;
10447 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
10448 /* Allocate num_ssid tCsrSSIDInfo structure */
10449 SsidInfo = scanRequest.SSIDs.SSIDList =
10450 ( tCsrSSIDInfo *)vos_mem_malloc(
10451 request->n_ssids*sizeof(tCsrSSIDInfo));
10452
10453 if(NULL == scanRequest.SSIDs.SSIDList)
10454 {
10455 hddLog(VOS_TRACE_LEVEL_ERROR,
10456 "%s: memory alloc failed SSIDInfo buffer", __func__);
10457 return -ENOMEM;
10458 }
10459
10460 /* copy all the ssid's and their length */
10461 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
10462 {
10463 /* get the ssid length */
10464 SsidInfo->SSID.length = request->ssids[j].ssid_len;
10465 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
10466 SsidInfo->SSID.length);
10467 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
10468 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
10469 j, SsidInfo->SSID.ssId);
10470 }
10471 /* set the scan type to active */
10472 scanRequest.scanType = eSIR_ACTIVE_SCAN;
10473 }
10474 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070010475 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010476 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10477 TRACE_CODE_HDD_CFG80211_SCAN,
10478 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070010479 /* set the scan type to active */
10480 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010481 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010482 else
10483 {
10484 /*Set the scan type to default type, in this case it is ACTIVE*/
10485 scanRequest.scanType = pScanInfo->scan_mode;
10486 }
10487 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
10488 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070010489
10490 /* set BSSType to default type */
10491 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
10492
10493 /*TODO: scan the requested channels only*/
10494
10495 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010496 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070010497 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010498 hddLog(VOS_TRACE_LEVEL_WARN,
10499 "No of Scan Channels exceeded limit: %d", request->n_channels);
10500 request->n_channels = MAX_CHANNEL;
10501 }
10502
10503 hddLog(VOS_TRACE_LEVEL_INFO,
10504 "No of Scan Channels: %d", request->n_channels);
10505
10506
10507 if( request->n_channels )
10508 {
10509 char chList [(request->n_channels*5)+1];
10510 int len;
10511 channelList = vos_mem_malloc( request->n_channels );
10512 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053010513 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010514 hddLog(VOS_TRACE_LEVEL_ERROR,
10515 "%s: memory alloc failed channelList", __func__);
10516 status = -ENOMEM;
10517 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053010518 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010519
10520 for( i = 0, len = 0; i < request->n_channels ; i++ )
10521 {
10522 channelList[i] = request->channels[i]->hw_value;
10523 len += snprintf(chList+len, 5, "%d ", channelList[i]);
10524 }
10525
Nirav Shah20ac06f2013-12-12 18:14:06 +053010526 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010527 "Channel-List: %s ", chList);
10528 }
c_hpothu53512302014-04-15 18:49:53 +053010529
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010530 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
10531 scanRequest.ChannelInfo.ChannelList = channelList;
10532
10533 /* set requestType to full scan */
10534 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10535
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010536 /* if there is back to back scan happening in driver with in
10537 * nDeferScanTimeInterval interval driver should defer new scan request
10538 * and should provide last cached scan results instead of new channel list.
10539 * This rule is not applicable if scan is p2p scan.
10540 * This condition will work only in case when last request no of channels
10541 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053010542 * This should be done only in connected state
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010543 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010544
Agarwal Ashish57e84372014-12-05 18:26:53 +053010545 if ((VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
10546 {
10547 if ( pScanInfo->last_scan_timestamp !=0 &&
10548 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10549 {
10550 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
10551 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
10552 vos_mem_compare(pScanInfo->last_scan_channelList,
10553 channelList, pScanInfo->last_scan_numChannels))
10554 {
10555 hddLog(VOS_TRACE_LEVEL_WARN,
10556 " New and old station scan time differ is less then %u",
10557 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10558
10559 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010560 pAdapter);
10561
Agarwal Ashish57e84372014-12-05 18:26:53 +053010562 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010563 "Return old cached scan as all channels and no of channels are same");
10564
Agarwal Ashish57e84372014-12-05 18:26:53 +053010565 if (0 > ret)
10566 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010567
Agarwal Ashish57e84372014-12-05 18:26:53 +053010568 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010569
10570 status = eHAL_STATUS_SUCCESS;
10571 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053010572 }
10573 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010574 }
10575
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010576 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10577 * search (Flush on both full scan and social scan but not on single
10578 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10579 */
10580
10581 /* Supplicant does single channel scan after 8-way handshake
10582 * and in that case driver shoudnt flush scan results. If
10583 * driver flushes the scan results here and unfortunately if
10584 * the AP doesnt respond to our probe req then association
10585 * fails which is not desired
10586 */
10587
10588 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
10589 {
10590 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
10591 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
10592 pAdapter->sessionId );
10593 }
10594
10595 if( request->ie_len )
10596 {
10597 /* save this for future association (join requires this) */
10598 /*TODO: Array needs to be converted to dynamic allocation,
10599 * as multiple ie.s can be sent in cfg80211_scan_request structure
10600 * CR 597966
10601 */
10602 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
10603 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
10604 pScanInfo->scanAddIE.length = request->ie_len;
10605
10606 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10607 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10608 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010609 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010610 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070010611 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010612 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
10613 memcpy( pwextBuf->roamProfile.addIEScan,
10614 request->ie, request->ie_len);
10615 }
10616 else
10617 {
10618 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
10619 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070010620 }
10621
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010622 }
10623 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
10624 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
10625
10626 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
10627 request->ie_len);
10628 if (pP2pIe != NULL)
10629 {
10630#ifdef WLAN_FEATURE_P2P_DEBUG
10631 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
10632 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
10633 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053010634 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010635 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
10636 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10637 "Go nego completed to Connection is started");
10638 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10639 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053010640 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010641 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
10642 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010643 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010644 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
10645 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10646 "Disconnected state to Connection is started");
10647 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10648 "for 4way Handshake");
10649 }
10650#endif
10651
10652 /* no_cck will be set during p2p find to disable 11b rates */
10653 if(TRUE == request->no_cck)
10654 {
10655 hddLog(VOS_TRACE_LEVEL_INFO,
10656 "%s: This is a P2P Search", __func__);
10657 scanRequest.p2pSearch = 1;
10658
10659 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053010660 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010661 /* set requestType to P2P Discovery */
10662 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
10663 }
10664
10665 /*
10666 Skip Dfs Channel in case of P2P Search
10667 if it is set in ini file
10668 */
10669 if(cfg_param->skipDfsChnlInP2pSearch)
10670 {
10671 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010672 }
10673 else
10674 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010675 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010676 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010677
Agarwal Ashish4f616132013-12-30 23:32:50 +053010678 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010679 }
10680 }
10681
10682 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
10683
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010684#ifdef FEATURE_WLAN_TDLS
10685 /* if tdls disagree scan right now, return immediately.
10686 tdls will schedule the scan when scan is allowed. (return SUCCESS)
10687 or will reject the scan if any TDLS is in progress. (return -EBUSY)
10688 */
10689 status = wlan_hdd_tdls_scan_callback (pAdapter,
10690 wiphy,
10691#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10692 dev,
10693#endif
10694 request);
10695 if(status <= 0)
10696 {
10697 if(!status)
10698 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
10699 "scan rejected %d", __func__, status);
10700 else
10701 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
10702 __func__, status);
10703
10704 return status;
10705 }
10706#endif
10707
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010708 /* acquire the wakelock to avoid the apps suspend during the scan. To
10709 * address the following issues.
10710 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
10711 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
10712 * for long time, this result in apps running at full power for long time.
10713 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
10714 * be stuck in full power because of resume BMPS
10715 */
10716 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -070010717
Nirav Shah20ac06f2013-12-12 18:14:06 +053010718 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10719 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010720 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
10721 scanRequest.requestType, scanRequest.scanType,
10722 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053010723 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
10724
Siddharth Bhal76972212014-10-15 16:22:51 +053010725 if (pHddCtx->spoofMacAddr.isEnabled)
10726 {
10727 hddLog(VOS_TRACE_LEVEL_INFO,
10728 "%s: MAC Spoofing enabled for current scan", __func__);
10729 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
10730 * to fill TxBds for probe request during current scan
10731 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053010732 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053010733 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053010734
10735 if(status != VOS_STATUS_SUCCESS)
10736 {
10737 hdd_allow_suspend();
10738 status = -EFAULT;
10739 goto free_mem;
10740 }
Siddharth Bhal76972212014-10-15 16:22:51 +053010741 }
10742
Jeff Johnsone7245742012-09-05 17:12:55 -070010743 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010744 pAdapter->sessionId, &scanRequest, &scanId,
10745 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070010746
Jeff Johnson295189b2012-06-20 16:38:30 -070010747 if (eHAL_STATUS_SUCCESS != status)
10748 {
10749 hddLog(VOS_TRACE_LEVEL_ERROR,
10750 "%s: sme_ScanRequest returned error %d", __func__, status);
10751 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010752 if(eHAL_STATUS_RESOURCES == status)
10753 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010754 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
10755 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010756 status = -EBUSY;
10757 } else {
10758 status = -EIO;
10759 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010760 hdd_allow_suspend();
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010761
10762#ifdef FEATURE_WLAN_TDLS
10763 wlan_hdd_tdls_scan_done_callback(pAdapter);
10764#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010765 goto free_mem;
10766 }
10767
10768 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010769 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070010770 pAdapter->request = request;
10771 pScanInfo->scanId = scanId;
10772
10773 complete(&pScanInfo->scan_req_completion_event);
10774
10775free_mem:
10776 if( scanRequest.SSIDs.SSIDList )
10777 {
10778 vos_mem_free(scanRequest.SSIDs.SSIDList);
10779 }
10780
10781 if( channelList )
10782 vos_mem_free( channelList );
10783
10784 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010785 return status;
10786}
10787
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010788int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
10789#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10790 struct net_device *dev,
10791#endif
10792 struct cfg80211_scan_request *request)
10793{
10794 int ret;
10795
10796 vos_ssr_protect(__func__);
10797 ret = __wlan_hdd_cfg80211_scan(wiphy,
10798#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10799 dev,
10800#endif
10801 request);
10802 vos_ssr_unprotect(__func__);
10803
10804 return ret;
10805}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010806
10807void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
10808{
10809 v_U8_t iniDot11Mode =
10810 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
10811 eHddDot11Mode hddDot11Mode = iniDot11Mode;
10812
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010813 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
10814 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010815 switch ( iniDot11Mode )
10816 {
10817 case eHDD_DOT11_MODE_AUTO:
10818 case eHDD_DOT11_MODE_11ac:
10819 case eHDD_DOT11_MODE_11ac_ONLY:
10820#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053010821 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
10822 sme_IsFeatureSupportedByFW(DOT11AC) )
10823 hddDot11Mode = eHDD_DOT11_MODE_11ac;
10824 else
10825 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010826#else
10827 hddDot11Mode = eHDD_DOT11_MODE_11n;
10828#endif
10829 break;
10830 case eHDD_DOT11_MODE_11n:
10831 case eHDD_DOT11_MODE_11n_ONLY:
10832 hddDot11Mode = eHDD_DOT11_MODE_11n;
10833 break;
10834 default:
10835 hddDot11Mode = iniDot11Mode;
10836 break;
10837 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010838#ifdef WLAN_FEATURE_AP_HT40_24G
10839 if (operationChannel > SIR_11B_CHANNEL_END)
10840#endif
10841 {
10842 /* This call decides required channel bonding mode */
10843 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010844 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
10845 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010846 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010847}
10848
Jeff Johnson295189b2012-06-20 16:38:30 -070010849/*
10850 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010851 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010852 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010853int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010854 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010855{
10856 int status = 0;
10857 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080010858 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010859 v_U32_t roamId;
10860 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070010861 eCsrAuthType RSNAuthType;
10862
10863 ENTER();
10864
10865 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080010866 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10867
10868 status = wlan_hdd_validate_context(pHddCtx);
10869 if (status)
10870 {
Yue Mae36e3552014-03-05 17:06:20 -080010871 return status;
10872 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010873
Jeff Johnson295189b2012-06-20 16:38:30 -070010874 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
10875 {
10876 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
10877 return -EINVAL;
10878 }
10879
10880 pRoamProfile = &pWextState->roamProfile;
10881
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010882 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070010883 {
Jeff Johnsone7245742012-09-05 17:12:55 -070010884 hdd_station_ctx_t *pHddStaCtx;
10885 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010886
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010887 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070010888 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
10889 {
10890 /*QoS not enabled in cfg file*/
10891 pRoamProfile->uapsd_mask = 0;
10892 }
10893 else
10894 {
10895 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010896 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070010897 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
10898 }
10899
10900 pRoamProfile->SSIDs.numOfSSIDs = 1;
10901 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
10902 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010903 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070010904 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
10905 ssid, ssid_len);
10906
10907 if (bssid)
10908 {
10909 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
10910 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
10911 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010912 /* Save BSSID in seperate variable as well, as RoamProfile
10913 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070010914 case of join failure we should send valid BSSID to supplicant
10915 */
10916 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
10917 WNI_CFG_BSSID_LEN);
10918 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070010919 else
10920 {
10921 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
10922 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010923
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010924 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
10925 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010926 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
10927 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010928 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010929 /*set gen ie*/
10930 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
10931 /*set auth*/
10932 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
10933 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010934#ifdef FEATURE_WLAN_WAPI
10935 if (pAdapter->wapi_info.nWapiMode)
10936 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010937 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010938 switch (pAdapter->wapi_info.wapiAuthMode)
10939 {
10940 case WAPI_AUTH_MODE_PSK:
10941 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010942 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010943 pAdapter->wapi_info.wapiAuthMode);
10944 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
10945 break;
10946 }
10947 case WAPI_AUTH_MODE_CERT:
10948 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010949 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010950 pAdapter->wapi_info.wapiAuthMode);
10951 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
10952 break;
10953 }
10954 } // End of switch
10955 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
10956 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
10957 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010958 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010959 pRoamProfile->AuthType.numEntries = 1;
10960 pRoamProfile->EncryptionType.numEntries = 1;
10961 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10962 pRoamProfile->mcEncryptionType.numEntries = 1;
10963 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10964 }
10965 }
10966#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010967#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010968 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010969 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10970 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
10971 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010972 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
10973 sizeof (tSirGtkOffloadParams));
10974 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010975 }
10976#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010977 pRoamProfile->csrPersona = pAdapter->device_mode;
10978
Jeff Johnson32d95a32012-09-10 13:15:23 -070010979 if( operatingChannel )
10980 {
10981 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
10982 pRoamProfile->ChannelInfo.numOfChannels = 1;
10983 }
Chet Lanctot186b5732013-03-18 10:26:30 -070010984 else
10985 {
10986 pRoamProfile->ChannelInfo.ChannelList = NULL;
10987 pRoamProfile->ChannelInfo.numOfChannels = 0;
10988 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010989 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
10990 {
10991 hdd_select_cbmode(pAdapter,operatingChannel);
10992 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010993
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010994 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
10995 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010996 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010997 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010998 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
10999 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011000 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11001 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053011002 {
11003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11004 "%s: Set HDD connState to eConnectionState_Connecting",
11005 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011006 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
11007 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053011008 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011009 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011010 pAdapter->sessionId, pRoamProfile, &roamId);
11011
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011012 if ((eHAL_STATUS_SUCCESS != status) &&
11013 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11014 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011015
11016 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011017 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
11018 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
11019 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011020 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011021 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011022 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011023
11024 pRoamProfile->ChannelInfo.ChannelList = NULL;
11025 pRoamProfile->ChannelInfo.numOfChannels = 0;
11026
Jeff Johnson295189b2012-06-20 16:38:30 -070011027 }
11028 else
11029 {
11030 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
11031 return -EINVAL;
11032 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011033 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011034 return status;
11035}
11036
11037/*
11038 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
11039 * This function is used to set the authentication type (OPEN/SHARED).
11040 *
11041 */
11042static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
11043 enum nl80211_auth_type auth_type)
11044{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011045 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011046 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11047
11048 ENTER();
11049
11050 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011051 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070011052 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011053 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011054 hddLog(VOS_TRACE_LEVEL_INFO,
11055 "%s: set authentication type to AUTOSWITCH", __func__);
11056 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
11057 break;
11058
11059 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011060#ifdef WLAN_FEATURE_VOWIFI_11R
11061 case NL80211_AUTHTYPE_FT:
11062#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011063 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011064 "%s: set authentication type to OPEN", __func__);
11065 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11066 break;
11067
11068 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011069 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011070 "%s: set authentication type to SHARED", __func__);
11071 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
11072 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011073#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011074 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011075 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011076 "%s: set authentication type to CCKM WPA", __func__);
11077 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
11078 break;
11079#endif
11080
11081
11082 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011083 hddLog(VOS_TRACE_LEVEL_ERROR,
11084 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011085 auth_type);
11086 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
11087 return -EINVAL;
11088 }
11089
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011090 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011091 pHddStaCtx->conn_info.authType;
11092 return 0;
11093}
11094
11095/*
11096 * FUNCTION: wlan_hdd_set_akm_suite
11097 * This function is used to set the key mgmt type(PSK/8021x).
11098 *
11099 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011100static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011101 u32 key_mgmt
11102 )
11103{
11104 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11105 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053011106 /* Should be in ieee802_11_defs.h */
11107#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
11108#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070011109 /*set key mgmt type*/
11110 switch(key_mgmt)
11111 {
11112 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053011113 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011114#ifdef WLAN_FEATURE_VOWIFI_11R
11115 case WLAN_AKM_SUITE_FT_PSK:
11116#endif
11117 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070011118 __func__);
11119 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
11120 break;
11121
11122 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053011123 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011124#ifdef WLAN_FEATURE_VOWIFI_11R
11125 case WLAN_AKM_SUITE_FT_8021X:
11126#endif
11127 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070011128 __func__);
11129 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11130 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011131#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011132#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
11133#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
11134 case WLAN_AKM_SUITE_CCKM:
11135 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
11136 __func__);
11137 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
11138 break;
11139#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070011140#ifndef WLAN_AKM_SUITE_OSEN
11141#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
11142 case WLAN_AKM_SUITE_OSEN:
11143 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
11144 __func__);
11145 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11146 break;
11147#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011148
11149 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011150 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011151 __func__, key_mgmt);
11152 return -EINVAL;
11153
11154 }
11155 return 0;
11156}
11157
11158/*
11159 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011160 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070011161 * (NONE/WEP40/WEP104/TKIP/CCMP).
11162 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011163static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
11164 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070011165 bool ucast
11166 )
11167{
11168 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011169 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011170 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11171
11172 ENTER();
11173
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011174 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011175 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011176 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070011177 __func__, cipher);
11178 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11179 }
11180 else
11181 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011182
Jeff Johnson295189b2012-06-20 16:38:30 -070011183 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011184 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011185 {
11186 case IW_AUTH_CIPHER_NONE:
11187 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11188 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011189
Jeff Johnson295189b2012-06-20 16:38:30 -070011190 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011191 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070011192 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011193
Jeff Johnson295189b2012-06-20 16:38:30 -070011194 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011195 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070011196 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011197
Jeff Johnson295189b2012-06-20 16:38:30 -070011198 case WLAN_CIPHER_SUITE_TKIP:
11199 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
11200 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011201
Jeff Johnson295189b2012-06-20 16:38:30 -070011202 case WLAN_CIPHER_SUITE_CCMP:
11203 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11204 break;
11205#ifdef FEATURE_WLAN_WAPI
11206 case WLAN_CIPHER_SUITE_SMS4:
11207 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
11208 break;
11209#endif
11210
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011211#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011212 case WLAN_CIPHER_SUITE_KRK:
11213 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
11214 break;
11215#endif
11216 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011217 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011218 __func__, cipher);
11219 return -EOPNOTSUPP;
11220 }
11221 }
11222
11223 if (ucast)
11224 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011225 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011226 __func__, encryptionType);
11227 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11228 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011229 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011230 encryptionType;
11231 }
11232 else
11233 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011234 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011235 __func__, encryptionType);
11236 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
11237 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
11238 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
11239 }
11240
11241 return 0;
11242}
11243
11244
11245/*
11246 * FUNCTION: wlan_hdd_cfg80211_set_ie
11247 * This function is used to parse WPA/RSN IE's.
11248 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011249int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
11250 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070011251 size_t ie_len
11252 )
11253{
11254 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11255 u8 *genie = ie;
11256 v_U16_t remLen = ie_len;
11257#ifdef FEATURE_WLAN_WAPI
11258 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
11259 u16 *tmp;
11260 v_U16_t akmsuiteCount;
11261 int *akmlist;
11262#endif
11263 ENTER();
11264
11265 /* clear previous assocAddIE */
11266 pWextState->assocAddIE.length = 0;
11267 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011268 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011269
11270 while (remLen >= 2)
11271 {
11272 v_U16_t eLen = 0;
11273 v_U8_t elementId;
11274 elementId = *genie++;
11275 eLen = *genie++;
11276 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011277
Arif Hussain6d2a3322013-11-17 19:50:10 -080011278 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070011279 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011280
11281 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070011282 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011283 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011284 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 -070011285 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011286 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011287 "%s: Invalid WPA IE", __func__);
11288 return -EINVAL;
11289 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011290 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070011291 {
11292 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011293 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011294 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011295
Jeff Johnson295189b2012-06-20 16:38:30 -070011296 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11297 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011298 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
11299 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011300 VOS_ASSERT(0);
11301 return -ENOMEM;
11302 }
11303 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11304 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11305 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011306
Jeff Johnson295189b2012-06-20 16:38:30 -070011307 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
11308 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11309 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11310 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011311 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
11312 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011313 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
11314 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11315 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
11316 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
11317 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
11318 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011319 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053011320 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011321 {
11322 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011323 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011324 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011325
Jeff Johnson295189b2012-06-20 16:38:30 -070011326 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11327 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011328 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11329 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011330 VOS_ASSERT(0);
11331 return -ENOMEM;
11332 }
11333 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11334 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11335 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011336
Jeff Johnson295189b2012-06-20 16:38:30 -070011337 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11338 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11339 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011340#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011341 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
11342 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011343 /*Consider WFD IE, only for P2P Client */
11344 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11345 {
11346 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011347 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011348 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011349
Jeff Johnson295189b2012-06-20 16:38:30 -070011350 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11351 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011352 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11353 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011354 VOS_ASSERT(0);
11355 return -ENOMEM;
11356 }
11357 // WFD IE is saved to Additional IE ; it should be accumulated to handle
11358 // WPS IE + P2P IE + WFD IE
11359 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11360 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011361
Jeff Johnson295189b2012-06-20 16:38:30 -070011362 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11363 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11364 }
11365#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011366 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011367 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011368 HS20_OUI_TYPE_SIZE)) )
11369 {
11370 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011371 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011372 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011373
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011374 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11375 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011376 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11377 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011378 VOS_ASSERT(0);
11379 return -ENOMEM;
11380 }
11381 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11382 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011383
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011384 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11385 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11386 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011387 /* Appending OSEN Information Element in Assiciation Request */
11388 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
11389 OSEN_OUI_TYPE_SIZE)) )
11390 {
11391 v_U16_t curAddIELen = pWextState->assocAddIE.length;
11392 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
11393 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011394
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011395 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11396 {
11397 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11398 "Need bigger buffer space");
11399 VOS_ASSERT(0);
11400 return -ENOMEM;
11401 }
11402 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11403 pWextState->assocAddIE.length += eLen + 2;
11404
11405 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
11406 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11407 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11408 }
11409
11410 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011411 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
11412
11413 /* populating as ADDIE in beacon frames */
11414 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11415 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
11416 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
11417 {
11418 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11419 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
11420 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11421 {
11422 hddLog(LOGE,
11423 "Coldn't pass "
11424 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
11425 }
11426 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
11427 else
11428 hddLog(LOGE,
11429 "Could not pass on "
11430 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
11431
11432 /* IBSS mode doesn't contain params->proberesp_ies still
11433 beaconIE's need to be populated in probe response frames */
11434 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
11435 {
11436 u16 rem_probe_resp_ie_len = eLen + 2;
11437 u8 probe_rsp_ie_len[3] = {0};
11438 u8 counter = 0;
11439
11440 /* Check Probe Resp Length if it is greater then 255 then
11441 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
11442 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
11443 not able Store More then 255 bytes into One Variable */
11444
11445 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
11446 {
11447 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
11448 {
11449 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
11450 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
11451 }
11452 else
11453 {
11454 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
11455 rem_probe_resp_ie_len = 0;
11456 }
11457 }
11458
11459 rem_probe_resp_ie_len = 0;
11460
11461 if (probe_rsp_ie_len[0] > 0)
11462 {
11463 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11464 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
11465 (tANI_U8*)(genie - 2),
11466 probe_rsp_ie_len[0], NULL,
11467 eANI_BOOLEAN_FALSE)
11468 == eHAL_STATUS_FAILURE)
11469 {
11470 hddLog(LOGE,
11471 "Could not pass"
11472 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
11473 }
11474 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
11475 }
11476
11477 if (probe_rsp_ie_len[1] > 0)
11478 {
11479 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11480 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
11481 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11482 probe_rsp_ie_len[1], NULL,
11483 eANI_BOOLEAN_FALSE)
11484 == eHAL_STATUS_FAILURE)
11485 {
11486 hddLog(LOGE,
11487 "Could not pass"
11488 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
11489 }
11490 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
11491 }
11492
11493 if (probe_rsp_ie_len[2] > 0)
11494 {
11495 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11496 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
11497 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11498 probe_rsp_ie_len[2], NULL,
11499 eANI_BOOLEAN_FALSE)
11500 == eHAL_STATUS_FAILURE)
11501 {
11502 hddLog(LOGE,
11503 "Could not pass"
11504 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
11505 }
11506 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
11507 }
11508
11509 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11510 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
11511 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11512 {
11513 hddLog(LOGE,
11514 "Could not pass"
11515 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
11516 }
11517 }
11518 else
11519 {
11520 // Reset WNI_CFG_PROBE_RSP Flags
11521 wlan_hdd_reset_prob_rspies(pAdapter);
11522
11523 hddLog(VOS_TRACE_LEVEL_INFO,
11524 "%s: No Probe Response IE received in set beacon",
11525 __func__);
11526 }
11527 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011528 break;
11529 case DOT11F_EID_RSN:
11530 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11531 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11532 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11533 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11534 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11535 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053011536
11537 /* Appending Extended Capabilities with Interworking bit set
11538 * in Assoc Req.
11539 *
11540 * In assoc req this EXT Cap will only be taken into account if
11541 * interworkingService bit is set to 1. Currently
11542 * driver is only interested in interworkingService capability
11543 * from supplicant. If in future any other EXT Cap info is
11544 * required from supplicat, it needs to be handled while
11545 * sending Assoc Req in LIM.
11546 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011547 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011548 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011549 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011550 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011551 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011552
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011553 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11554 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011555 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11556 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011557 VOS_ASSERT(0);
11558 return -ENOMEM;
11559 }
11560 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11561 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011562
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011563 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11564 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11565 break;
11566 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011567#ifdef FEATURE_WLAN_WAPI
11568 case WLAN_EID_WAPI:
11569 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011570 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011571 pAdapter->wapi_info.nWapiMode);
11572 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011573 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070011574 akmsuiteCount = WPA_GET_LE16(tmp);
11575 tmp = tmp + 1;
11576 akmlist = (int *)(tmp);
11577 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
11578 {
11579 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
11580 }
11581 else
11582 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011583 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070011584 VOS_ASSERT(0);
11585 return -EINVAL;
11586 }
11587
11588 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
11589 {
11590 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011591 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011592 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011593 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011594 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011595 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011596 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011597 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011598 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
11599 }
11600 break;
11601#endif
11602 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011603 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011604 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011605 /* when Unknown IE is received we should break and continue
11606 * to the next IE in the buffer instead we were returning
11607 * so changing this to break */
11608 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011609 }
11610 genie += eLen;
11611 remLen -= eLen;
11612 }
11613 EXIT();
11614 return 0;
11615}
11616
11617/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053011618 * FUNCTION: hdd_isWPAIEPresent
11619 * Parse the received IE to find the WPA IE
11620 *
11621 */
11622static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
11623{
11624 v_U8_t eLen = 0;
11625 v_U16_t remLen = ie_len;
11626 v_U8_t elementId = 0;
11627
11628 while (remLen >= 2)
11629 {
11630 elementId = *ie++;
11631 eLen = *ie++;
11632 remLen -= 2;
11633 if (eLen > remLen)
11634 {
11635 hddLog(VOS_TRACE_LEVEL_ERROR,
11636 "%s: IE length is wrong %d", __func__, eLen);
11637 return FALSE;
11638 }
11639 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
11640 {
11641 /* OUI - 0x00 0X50 0XF2
11642 WPA Information Element - 0x01
11643 WPA version - 0x01*/
11644 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
11645 return TRUE;
11646 }
11647 ie += eLen;
11648 remLen -= eLen;
11649 }
11650 return FALSE;
11651}
11652
11653/*
Jeff Johnson295189b2012-06-20 16:38:30 -070011654 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011655 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011656 * parameters during connect operation.
11657 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011658int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011659 struct cfg80211_connect_params *req
11660 )
11661{
11662 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011663 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011664 ENTER();
11665
11666 /*set wpa version*/
11667 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
11668
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011669 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011670 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053011671 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011672 {
11673 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11674 }
11675 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
11676 {
11677 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11678 }
11679 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011680
11681 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011682 pWextState->wpaVersion);
11683
11684 /*set authentication type*/
11685 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
11686
11687 if (0 > status)
11688 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011689 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011690 "%s: failed to set authentication type ", __func__);
11691 return status;
11692 }
11693
11694 /*set key mgmt type*/
11695 if (req->crypto.n_akm_suites)
11696 {
11697 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
11698 if (0 > status)
11699 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011700 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070011701 __func__);
11702 return status;
11703 }
11704 }
11705
11706 /*set pairwise cipher type*/
11707 if (req->crypto.n_ciphers_pairwise)
11708 {
11709 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
11710 req->crypto.ciphers_pairwise[0], true);
11711 if (0 > status)
11712 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011713 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011714 "%s: failed to set unicast cipher type", __func__);
11715 return status;
11716 }
11717 }
11718 else
11719 {
11720 /*Reset previous cipher suite to none*/
11721 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
11722 if (0 > status)
11723 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011724 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011725 "%s: failed to set unicast cipher type", __func__);
11726 return status;
11727 }
11728 }
11729
11730 /*set group cipher type*/
11731 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
11732 false);
11733
11734 if (0 > status)
11735 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011736 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070011737 __func__);
11738 return status;
11739 }
11740
Chet Lanctot186b5732013-03-18 10:26:30 -070011741#ifdef WLAN_FEATURE_11W
11742 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
11743#endif
11744
Jeff Johnson295189b2012-06-20 16:38:30 -070011745 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
11746 if (req->ie_len)
11747 {
11748 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
11749 if ( 0 > status)
11750 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011751 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011752 __func__);
11753 return status;
11754 }
11755 }
11756
11757 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011758 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011759 {
11760 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
11761 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
11762 )
11763 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011764 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070011765 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
11766 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011767 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011768 __func__);
11769 return -EOPNOTSUPP;
11770 }
11771 else
11772 {
11773 u8 key_len = req->key_len;
11774 u8 key_idx = req->key_idx;
11775
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011776 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011777 && (CSR_MAX_NUM_KEY > key_idx)
11778 )
11779 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011780 hddLog(VOS_TRACE_LEVEL_INFO,
11781 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011782 __func__, key_idx, key_len);
11783 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011784 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011785 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011786 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011787 (u8)key_len;
11788 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
11789 }
11790 }
11791 }
11792 }
11793
11794 return status;
11795}
11796
11797/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011798 * FUNCTION: wlan_hdd_try_disconnect
11799 * This function is used to disconnect from previous
11800 * connection
11801 */
11802static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
11803{
11804 long ret = 0;
11805 hdd_station_ctx_t *pHddStaCtx;
11806 eMib_dot11DesiredBssType connectedBssType;
11807
11808 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11809
11810 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
11811
11812 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
11813 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
11814 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
11815 {
11816 /* Issue disconnect to CSR */
11817 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11818 if( eHAL_STATUS_SUCCESS ==
11819 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11820 pAdapter->sessionId,
11821 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11822 {
11823 ret = wait_for_completion_interruptible_timeout(
11824 &pAdapter->disconnect_comp_var,
11825 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11826 if (0 >= ret)
11827 {
11828 hddLog(LOGE, FL("Failed to receive disconnect event"));
11829 return -EALREADY;
11830 }
11831 }
11832 }
11833 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
11834 {
11835 ret = wait_for_completion_interruptible_timeout(
11836 &pAdapter->disconnect_comp_var,
11837 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11838 if (0 >= ret)
11839 {
11840 hddLog(LOGE, FL("Failed to receive disconnect event"));
11841 return -EALREADY;
11842 }
11843 }
11844
11845 return 0;
11846}
11847
11848/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053011849 * FUNCTION: __wlan_hdd_cfg80211_connect
11850 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011851 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011852static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011853 struct net_device *ndev,
11854 struct cfg80211_connect_params *req
11855 )
11856{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011857 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011858 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011859 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053011860 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011861
11862 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011863
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011864 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11865 TRACE_CODE_HDD_CFG80211_CONNECT,
11866 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011867 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011868 "%s: device_mode = %s (%d)", __func__,
11869 hdd_device_modetoString(pAdapter->device_mode),
11870 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011871
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011872 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011873 if (!pHddCtx)
11874 {
11875 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11876 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011877 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011878 }
11879
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011880 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011881 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011882 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011883 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011884 }
11885
Agarwal Ashish51325b52014-06-16 16:50:49 +053011886 if (vos_max_concurrent_connections_reached()) {
11887 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11888 return -ECONNREFUSED;
11889 }
11890
Jeff Johnson295189b2012-06-20 16:38:30 -070011891#ifdef WLAN_BTAMP_FEATURE
11892 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011893 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070011894 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011895 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011896 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011897 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070011898 }
11899#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011900
11901 //If Device Mode is Station Concurrent Sessions Exit BMps
11902 //P2P Mode will be taken care in Open/close adapter
11903 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011904 (vos_concurrent_open_sessions_running())) {
11905 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
11906 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011907 }
11908
11909 /*Try disconnecting if already in connected state*/
11910 status = wlan_hdd_try_disconnect(pAdapter);
11911 if ( 0 > status)
11912 {
11913 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11914 " connection"));
11915 return -EALREADY;
11916 }
11917
Jeff Johnson295189b2012-06-20 16:38:30 -070011918 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011919 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070011920
11921 if ( 0 > status)
11922 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011923 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070011924 __func__);
11925 return status;
11926 }
Mohit Khanna765234a2012-09-11 15:08:35 -070011927 if ( req->channel )
11928 {
11929 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
11930 req->ssid_len, req->bssid,
11931 req->channel->hw_value);
11932 }
11933 else
11934 {
11935 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011936 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070011937 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011938
Sushant Kaushikd7083982015-03-18 14:33:24 +053011939 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011940 {
11941 //ReEnable BMPS if disabled
11942 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
11943 (NULL != pHddCtx))
11944 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011945 if (pHddCtx->hdd_wlan_suspended)
11946 {
11947 hdd_set_pwrparams(pHddCtx);
11948 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011949 //ReEnable Bmps and Imps back
11950 hdd_enable_bmps_imps(pHddCtx);
11951 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011952 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011953 return status;
11954 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011955 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011956 EXIT();
11957 return status;
11958}
11959
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011960static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
11961 struct net_device *ndev,
11962 struct cfg80211_connect_params *req)
11963{
11964 int ret;
11965 vos_ssr_protect(__func__);
11966 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
11967 vos_ssr_unprotect(__func__);
11968
11969 return ret;
11970}
Jeff Johnson295189b2012-06-20 16:38:30 -070011971
11972/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011973 * FUNCTION: wlan_hdd_disconnect
11974 * This function is used to issue a disconnect request to SME
11975 */
11976int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
11977{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011978 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011979 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011980 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011981 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011982
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011983 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011984
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011985 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011986 if (0 != status)
11987 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011988 return status;
11989 }
11990
11991 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011992
Agarwal Ashish47d18112014-08-04 19:55:07 +053011993 /* Need to apply spin lock before decreasing active sessions
11994 * as there can be chance for double decrement if context switch
11995 * Calls hdd_DisConnectHandler.
11996 */
11997
11998 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011999 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
12000 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012001 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
12002 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053012003 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
12004 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012005
Abhishek Singhf4669da2014-05-26 15:07:49 +053012006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053012007 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
12008
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012009 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012010
Mihir Shete182a0b22014-08-18 16:08:48 +053012011 /*
12012 * stop tx queues before deleting STA/BSS context from the firmware.
12013 * tx has to be disabled because the firmware can get busy dropping
12014 * the tx frames after BSS/STA has been deleted and will not send
12015 * back a response resulting in WDI timeout
12016 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053012017 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053012018 netif_tx_disable(pAdapter->dev);
12019 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012020
Mihir Shete182a0b22014-08-18 16:08:48 +053012021 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012022 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12023 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012024 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
12025 {
12026 hddLog(VOS_TRACE_LEVEL_INFO,
12027 FL("status = %d, already disconnected"),
12028 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012029
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012030 }
12031 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012032 {
12033 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012034 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012035 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012036 result = -EINVAL;
12037 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012038 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012039 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012040 &pAdapter->disconnect_comp_var,
12041 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012042 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012043 {
12044 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012045 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012046 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012047 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012048 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012049 {
12050 hddLog(VOS_TRACE_LEVEL_ERROR,
12051 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012052 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012053 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012054disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012055 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12056 FL("Set HDD connState to eConnectionState_NotConnected"));
12057 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
12058
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012059 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012060 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012061}
12062
12063
12064/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012065 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070012066 * This function is used to issue a disconnect request to SME
12067 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012068static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012069 struct net_device *dev,
12070 u16 reason
12071 )
12072{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012073 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012074 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012075 tCsrRoamProfile *pRoamProfile;
12076 hdd_station_ctx_t *pHddStaCtx;
12077 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012078#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012079 tANI_U8 staIdx;
12080#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012081
Jeff Johnson295189b2012-06-20 16:38:30 -070012082 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012083
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012084 if (!pAdapter) {
12085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
12086 return -EINVAL;
12087 }
12088
12089 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12090 if (!pHddStaCtx) {
12091 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
12092 return -EINVAL;
12093 }
12094
12095 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12096 status = wlan_hdd_validate_context(pHddCtx);
12097 if (0 != status)
12098 {
12099 return status;
12100 }
12101
12102 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
12103
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012104 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12105 TRACE_CODE_HDD_CFG80211_DISCONNECT,
12106 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012107 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
12108 __func__, hdd_device_modetoString(pAdapter->device_mode),
12109 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012110
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012111 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
12112 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070012113
Jeff Johnson295189b2012-06-20 16:38:30 -070012114 if (NULL != pRoamProfile)
12115 {
12116 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012117 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
12118 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070012119 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012120 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070012121 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012122 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012123 switch(reason)
12124 {
12125 case WLAN_REASON_MIC_FAILURE:
12126 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
12127 break;
12128
12129 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
12130 case WLAN_REASON_DISASSOC_AP_BUSY:
12131 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
12132 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
12133 break;
12134
12135 case WLAN_REASON_PREV_AUTH_NOT_VALID:
12136 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053012137 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070012138 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
12139 break;
12140
Jeff Johnson295189b2012-06-20 16:38:30 -070012141 default:
12142 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
12143 break;
12144 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012145 pScanInfo = &pHddCtx->scan_info;
12146 if (pScanInfo->mScanPending)
12147 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012148 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012149 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012150 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012151 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012152 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012153
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012154#ifdef FEATURE_WLAN_TDLS
12155 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012156 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012157 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012158 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
12159 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012160 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012161 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012162 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012164 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012165 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012166 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012167 status = sme_DeleteTdlsPeerSta(
12168 WLAN_HDD_GET_HAL_CTX(pAdapter),
12169 pAdapter->sessionId,
12170 mac);
12171 if (status != eHAL_STATUS_SUCCESS) {
12172 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
12173 return -EPERM;
12174 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012175 }
12176 }
12177#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012178 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012179 status = wlan_hdd_disconnect(pAdapter, reasonCode);
12180 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070012181 {
12182 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012183 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012184 __func__, (int)status );
12185 return -EINVAL;
12186 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012187 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012188 else
12189 {
12190 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
12191 "called while in %d state", __func__,
12192 pHddStaCtx->conn_info.connState);
12193 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012194 }
12195 else
12196 {
12197 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
12198 }
12199
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012200 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012201 return status;
12202}
12203
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012204static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
12205 struct net_device *dev,
12206 u16 reason
12207 )
12208{
12209 int ret;
12210 vos_ssr_protect(__func__);
12211 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
12212 vos_ssr_unprotect(__func__);
12213
12214 return ret;
12215}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012216
Jeff Johnson295189b2012-06-20 16:38:30 -070012217/*
12218 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012219 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012220 * settings in IBSS mode.
12221 */
12222static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012223 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012224 struct cfg80211_ibss_params *params
12225 )
12226{
12227 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012228 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012229 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12230 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012231
Jeff Johnson295189b2012-06-20 16:38:30 -070012232 ENTER();
12233
12234 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070012235 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070012236
12237 if (params->ie_len && ( NULL != params->ie) )
12238 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012239 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12240 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012241 {
12242 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12243 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12244 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012245 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012246 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012247 tDot11fIEWPA dot11WPAIE;
12248 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012249 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012250
Wilson Yang00256342013-10-10 23:13:38 -070012251 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012252 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12253 params->ie_len, DOT11F_EID_WPA);
12254 if ( NULL != ie )
12255 {
12256 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12257 // Unpack the WPA IE
12258 //Skip past the EID byte and length byte - and four byte WiFi OUI
12259 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
12260 &ie[2+4],
12261 ie[1] - 4,
12262 &dot11WPAIE);
12263 /*Extract the multicast cipher, the encType for unicast
12264 cipher for wpa-none is none*/
12265 encryptionType =
12266 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
12267 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012268 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012269
Jeff Johnson295189b2012-06-20 16:38:30 -070012270 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
12271
12272 if (0 > status)
12273 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012274 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012275 __func__);
12276 return status;
12277 }
12278 }
12279
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012280 pWextState->roamProfile.AuthType.authType[0] =
12281 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012282 eCSR_AUTH_TYPE_OPEN_SYSTEM;
12283
12284 if (params->privacy)
12285 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012286 /* Security enabled IBSS, At this time there is no information available
12287 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070012288 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012289 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070012290 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012291 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070012292 *enable privacy bit in beacons */
12293
12294 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12295 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012296 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
12297 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070012298 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12299 pWextState->roamProfile.EncryptionType.numEntries = 1;
12300 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070012301 return status;
12302}
12303
12304/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012305 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012306 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012307 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012308static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012309 struct net_device *dev,
12310 struct cfg80211_ibss_params *params
12311 )
12312{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012313 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012314 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12315 tCsrRoamProfile *pRoamProfile;
12316 int status;
krunal sonie9002db2013-11-25 14:24:17 -080012317 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012318 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12319 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012320
12321 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012322
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012323 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12324 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
12325 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012326 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012327 "%s: device_mode = %s (%d)", __func__,
12328 hdd_device_modetoString(pAdapter->device_mode),
12329 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012330
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012331 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012332 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012333 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012334 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012335 }
12336
12337 if (NULL == pWextState)
12338 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012339 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012340 __func__);
12341 return -EIO;
12342 }
12343
Agarwal Ashish51325b52014-06-16 16:50:49 +053012344 if (vos_max_concurrent_connections_reached()) {
12345 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12346 return -ECONNREFUSED;
12347 }
12348
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012349 /*Try disconnecting if already in connected state*/
12350 status = wlan_hdd_try_disconnect(pAdapter);
12351 if ( 0 > status)
12352 {
12353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12354 " IBSS connection"));
12355 return -EALREADY;
12356 }
12357
Jeff Johnson295189b2012-06-20 16:38:30 -070012358 pRoamProfile = &pWextState->roamProfile;
12359
12360 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
12361 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012362 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012363 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012364 return -EINVAL;
12365 }
12366
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012367 /* BSSID is provided by upper layers hence no need to AUTO generate */
12368 if (NULL != params->bssid) {
12369 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12370 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
12371 hddLog (VOS_TRACE_LEVEL_ERROR,
12372 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12373 return -EIO;
12374 }
12375 }
krunal sonie9002db2013-11-25 14:24:17 -080012376 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
12377 {
12378 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12379 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
12380 {
12381 hddLog (VOS_TRACE_LEVEL_ERROR,
12382 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12383 return -EIO;
12384 }
Sachin Ahuja46ff4912015-03-23 22:48:43 +053012385 params->bssid = vos_mem_malloc(VOS_MAC_ADDR_SIZE);
krunal sonie9002db2013-11-25 14:24:17 -080012386 if (!params->bssid)
12387 {
12388 hddLog (VOS_TRACE_LEVEL_ERROR,
12389 "%s:Failed memory allocation", __func__);
12390 return -EIO;
12391 }
12392 vos_mem_copy((v_U8_t *)params->bssid,
12393 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
12394 VOS_MAC_ADDR_SIZE);
12395 alloc_bssid = VOS_TRUE;
12396 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012397
Jeff Johnson295189b2012-06-20 16:38:30 -070012398 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070012399 if (NULL !=
12400#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12401 params->chandef.chan)
12402#else
12403 params->channel)
12404#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012405 {
12406 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012407 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12408 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
12409 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12410 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012411
12412 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012413 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070012414 ieee80211_frequency_to_channel(
12415#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12416 params->chandef.chan->center_freq);
12417#else
12418 params->channel->center_freq);
12419#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012420
12421 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12422 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070012423 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012424 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
12425 __func__);
12426 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012427 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012428
12429 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012430 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012431 if (channelNum == validChan[indx])
12432 {
12433 break;
12434 }
12435 }
12436 if (indx >= numChans)
12437 {
12438 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012439 __func__, channelNum);
12440 return -EINVAL;
12441 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012442 /* Set the Operational Channel */
12443 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
12444 channelNum);
12445 pRoamProfile->ChannelInfo.numOfChannels = 1;
12446 pHddStaCtx->conn_info.operationChannel = channelNum;
12447 pRoamProfile->ChannelInfo.ChannelList =
12448 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070012449 }
12450
12451 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012452 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070012453 if (status < 0)
12454 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012455 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070012456 __func__);
12457 return status;
12458 }
12459
12460 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012461 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012462 params->ssid_len, params->bssid,
12463 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012464
12465 if (0 > status)
12466 {
12467 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
12468 return status;
12469 }
12470
krunal sonie9002db2013-11-25 14:24:17 -080012471 if (NULL != params->bssid &&
12472 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
12473 alloc_bssid == VOS_TRUE)
12474 {
12475 vos_mem_free(params->bssid);
12476 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012477 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012478 return 0;
12479}
12480
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012481static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
12482 struct net_device *dev,
12483 struct cfg80211_ibss_params *params
12484 )
12485{
12486 int ret = 0;
12487
12488 vos_ssr_protect(__func__);
12489 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
12490 vos_ssr_unprotect(__func__);
12491
12492 return ret;
12493}
12494
Jeff Johnson295189b2012-06-20 16:38:30 -070012495/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012496 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012497 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012498 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012499static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012500 struct net_device *dev
12501 )
12502{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012503 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012504 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12505 tCsrRoamProfile *pRoamProfile;
12506 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012507 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012508
12509 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012510
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012511 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12512 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
12513 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012514 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012515 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012516 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012517 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012518 }
12519
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012520 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
12521 hdd_device_modetoString(pAdapter->device_mode),
12522 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012523 if (NULL == pWextState)
12524 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012525 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012526 __func__);
12527 return -EIO;
12528 }
12529
12530 pRoamProfile = &pWextState->roamProfile;
12531
12532 /* Issue disconnect only if interface type is set to IBSS */
12533 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
12534 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012535 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012536 __func__);
12537 return -EINVAL;
12538 }
12539
12540 /* Issue Disconnect request */
12541 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12542 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12543 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12544
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012545 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012546 return 0;
12547}
12548
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012549static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12550 struct net_device *dev
12551 )
12552{
12553 int ret = 0;
12554
12555 vos_ssr_protect(__func__);
12556 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12557 vos_ssr_unprotect(__func__);
12558
12559 return ret;
12560}
12561
Jeff Johnson295189b2012-06-20 16:38:30 -070012562/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012563 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012564 * This function is used to set the phy parameters
12565 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12566 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012567static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012568 u32 changed)
12569{
12570 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12571 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012572 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012573
12574 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012575
12576 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012577 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
12578 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012579
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012580 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012581 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012582 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012583 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012584 }
12585
Jeff Johnson295189b2012-06-20 16:38:30 -070012586 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
12587 {
12588 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
12589 WNI_CFG_RTS_THRESHOLD_STAMAX :
12590 wiphy->rts_threshold;
12591
12592 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012593 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070012594 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012595 hddLog(VOS_TRACE_LEVEL_ERROR,
12596 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012597 __func__, rts_threshold);
12598 return -EINVAL;
12599 }
12600
12601 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
12602 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012603 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012604 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012605 hddLog(VOS_TRACE_LEVEL_ERROR,
12606 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012607 __func__, rts_threshold);
12608 return -EIO;
12609 }
12610
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012611 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012612 rts_threshold);
12613 }
12614
12615 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
12616 {
12617 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
12618 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
12619 wiphy->frag_threshold;
12620
12621 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012622 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012623 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012624 hddLog(VOS_TRACE_LEVEL_ERROR,
12625 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012626 frag_threshold);
12627 return -EINVAL;
12628 }
12629
12630 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
12631 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012632 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012633 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012634 hddLog(VOS_TRACE_LEVEL_ERROR,
12635 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012636 __func__, frag_threshold);
12637 return -EIO;
12638 }
12639
12640 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
12641 frag_threshold);
12642 }
12643
12644 if ((changed & WIPHY_PARAM_RETRY_SHORT)
12645 || (changed & WIPHY_PARAM_RETRY_LONG))
12646 {
12647 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
12648 wiphy->retry_short :
12649 wiphy->retry_long;
12650
12651 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
12652 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
12653 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012654 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012655 __func__, retry_value);
12656 return -EINVAL;
12657 }
12658
12659 if (changed & WIPHY_PARAM_RETRY_SHORT)
12660 {
12661 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
12662 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012663 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012664 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012665 hddLog(VOS_TRACE_LEVEL_ERROR,
12666 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012667 __func__, retry_value);
12668 return -EIO;
12669 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012670 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012671 __func__, retry_value);
12672 }
12673 else if (changed & WIPHY_PARAM_RETRY_SHORT)
12674 {
12675 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
12676 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012677 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012678 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012679 hddLog(VOS_TRACE_LEVEL_ERROR,
12680 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012681 __func__, retry_value);
12682 return -EIO;
12683 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012684 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012685 __func__, retry_value);
12686 }
12687 }
12688
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012689 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012690 return 0;
12691}
12692
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012693static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
12694 u32 changed)
12695{
12696 int ret;
12697
12698 vos_ssr_protect(__func__);
12699 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
12700 vos_ssr_unprotect(__func__);
12701
12702 return ret;
12703}
12704
Jeff Johnson295189b2012-06-20 16:38:30 -070012705/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012706 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012707 * This function is used to set the txpower
12708 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012709static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012710#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12711 struct wireless_dev *wdev,
12712#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012713#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012714 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012715#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012716 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012717#endif
12718 int dbm)
12719{
12720 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012721 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012722 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12723 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012724 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012725
12726 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012727
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012728 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12729 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
12730 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012731 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012732 if (0 != status)
12733 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012734 return status;
12735 }
12736
12737 hHal = pHddCtx->hHal;
12738
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012739 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
12740 dbm, ccmCfgSetCallback,
12741 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012742 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012743 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012744 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
12745 return -EIO;
12746 }
12747
12748 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
12749 dbm);
12750
12751 switch(type)
12752 {
12753 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
12754 /* Fall through */
12755 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
12756 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
12757 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012758 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
12759 __func__);
12760 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012761 }
12762 break;
12763 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012764 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012765 __func__);
12766 return -EOPNOTSUPP;
12767 break;
12768 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012769 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
12770 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070012771 return -EIO;
12772 }
12773
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012774 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012775 return 0;
12776}
12777
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012778static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
12779#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12780 struct wireless_dev *wdev,
12781#endif
12782#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12783 enum tx_power_setting type,
12784#else
12785 enum nl80211_tx_power_setting type,
12786#endif
12787 int dbm)
12788{
12789 int ret;
12790 vos_ssr_protect(__func__);
12791 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
12792#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12793 wdev,
12794#endif
12795#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12796 type,
12797#else
12798 type,
12799#endif
12800 dbm);
12801 vos_ssr_unprotect(__func__);
12802
12803 return ret;
12804}
12805
Jeff Johnson295189b2012-06-20 16:38:30 -070012806/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012807 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012808 * This function is used to read the txpower
12809 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012810static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012811#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12812 struct wireless_dev *wdev,
12813#endif
12814 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070012815{
12816
12817 hdd_adapter_t *pAdapter;
12818 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012819 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012820
Jeff Johnsone7245742012-09-05 17:12:55 -070012821 ENTER();
12822
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012823 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012824 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012825 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012826 *dbm = 0;
12827 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012828 }
12829
Jeff Johnson295189b2012-06-20 16:38:30 -070012830 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
12831 if (NULL == pAdapter)
12832 {
12833 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
12834 return -ENOENT;
12835 }
12836
12837 wlan_hdd_get_classAstats(pAdapter);
12838 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
12839
Jeff Johnsone7245742012-09-05 17:12:55 -070012840 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012841 return 0;
12842}
12843
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012844static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
12845#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12846 struct wireless_dev *wdev,
12847#endif
12848 int *dbm)
12849{
12850 int ret;
12851
12852 vos_ssr_protect(__func__);
12853 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
12854#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12855 wdev,
12856#endif
12857 dbm);
12858 vos_ssr_unprotect(__func__);
12859
12860 return ret;
12861}
12862
12863
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012864static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070012865 u8* mac, struct station_info *sinfo)
12866{
12867 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12868 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12869 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053012870 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070012871
12872 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
12873 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012874
12875 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
12876 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
12877 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
12878 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
12879 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
12880 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
12881 tANI_U16 maxRate = 0;
12882 tANI_U16 myRate;
12883 tANI_U16 currentRate = 0;
12884 tANI_U8 maxSpeedMCS = 0;
12885 tANI_U8 maxMCSIdx = 0;
12886 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053012887 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012888 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012889 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012890
Leo Chang6f8870f2013-03-26 18:11:36 -070012891#ifdef WLAN_FEATURE_11AC
12892 tANI_U32 vht_mcs_map;
12893 eDataRate11ACMaxMcs vhtMaxMcs;
12894#endif /* WLAN_FEATURE_11AC */
12895
Jeff Johnsone7245742012-09-05 17:12:55 -070012896 ENTER();
12897
Jeff Johnson295189b2012-06-20 16:38:30 -070012898 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
12899 (0 == ssidlen))
12900 {
12901 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
12902 " Invalid ssidlen, %d", __func__, ssidlen);
12903 /*To keep GUI happy*/
12904 return 0;
12905 }
12906
Mukul Sharma811205f2014-07-09 21:07:30 +053012907 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
12908 {
12909 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12910 "%s: Roaming in progress, so unable to proceed this request", __func__);
12911 return 0;
12912 }
12913
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012914 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012915 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012916 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012917 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012918 }
12919
Jeff Johnson295189b2012-06-20 16:38:30 -070012920
Kiet Lam3b17fc82013-09-27 05:24:08 +053012921 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
12922 sinfo->filled |= STATION_INFO_SIGNAL;
12923
c_hpothu09f19542014-05-30 21:53:31 +053012924 wlan_hdd_get_station_stats(pAdapter);
12925 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
12926
12927 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053012928 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
12929 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053012930 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053012931 {
12932 rate_flags = pAdapter->maxRateFlags;
12933 }
c_hpothu44ff4e02014-05-08 00:13:57 +053012934
Jeff Johnson295189b2012-06-20 16:38:30 -070012935 //convert to the UI units of 100kbps
12936 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
12937
12938#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070012939 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 -070012940 sinfo->signal,
12941 pCfg->reportMaxLinkSpeed,
12942 myRate,
12943 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012944 (int) pCfg->linkSpeedRssiMid,
12945 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070012946 (int) rate_flags,
12947 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012948#endif //LINKSPEED_DEBUG_ENABLED
12949
12950 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
12951 {
12952 // we do not want to necessarily report the current speed
12953 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
12954 {
12955 // report the max possible speed
12956 rssidx = 0;
12957 }
12958 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
12959 {
12960 // report the max possible speed with RSSI scaling
12961 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
12962 {
12963 // report the max possible speed
12964 rssidx = 0;
12965 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012966 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070012967 {
12968 // report middle speed
12969 rssidx = 1;
12970 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012971 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
12972 {
12973 // report middle speed
12974 rssidx = 2;
12975 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012976 else
12977 {
12978 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012979 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070012980 }
12981 }
12982 else
12983 {
12984 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
12985 hddLog(VOS_TRACE_LEVEL_ERROR,
12986 "%s: Invalid value for reportMaxLinkSpeed: %u",
12987 __func__, pCfg->reportMaxLinkSpeed);
12988 rssidx = 0;
12989 }
12990
12991 maxRate = 0;
12992
12993 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012994 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
12995 OperationalRates, &ORLeng))
12996 {
12997 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12998 /*To keep GUI happy*/
12999 return 0;
13000 }
13001
Jeff Johnson295189b2012-06-20 16:38:30 -070013002 for (i = 0; i < ORLeng; i++)
13003 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013004 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013005 {
13006 /* Validate Rate Set */
13007 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
13008 {
13009 currentRate = supported_data_rate[j].supported_rate[rssidx];
13010 break;
13011 }
13012 }
13013 /* Update MAX rate */
13014 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13015 }
13016
13017 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013018 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
13019 ExtendedRates, &ERLeng))
13020 {
13021 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13022 /*To keep GUI happy*/
13023 return 0;
13024 }
13025
Jeff Johnson295189b2012-06-20 16:38:30 -070013026 for (i = 0; i < ERLeng; i++)
13027 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013028 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013029 {
13030 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
13031 {
13032 currentRate = supported_data_rate[j].supported_rate[rssidx];
13033 break;
13034 }
13035 }
13036 /* Update MAX rate */
13037 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13038 }
c_hpothu79aab322014-07-14 21:11:01 +053013039
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013040 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053013041 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013042 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053013043 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070013044 {
c_hpothu79aab322014-07-14 21:11:01 +053013045 if (rate_flags & eHAL_TX_RATE_VHT80)
13046 mode = 2;
13047 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
13048 mode = 1;
13049 else
13050 mode = 0;
13051
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013052 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
13053 MCSRates, &MCSLeng))
13054 {
13055 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13056 /*To keep GUI happy*/
13057 return 0;
13058 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013059 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070013060#ifdef WLAN_FEATURE_11AC
13061 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013062 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070013063 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013064 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013065 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070013066 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070013067 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013068 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013069 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013070 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070013071 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013072 maxMCSIdx = 7;
13073 }
13074 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
13075 {
13076 maxMCSIdx = 8;
13077 }
13078 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
13079 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013080 //VHT20 is supporting 0~8
13081 if (rate_flags & eHAL_TX_RATE_VHT20)
13082 maxMCSIdx = 8;
13083 else
13084 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070013085 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013086
c_hpothu79aab322014-07-14 21:11:01 +053013087 if (0 != rssidx)/*check for scaled */
13088 {
13089 //get middle rate MCS index if rssi=1/2
13090 for (i=0; i <= maxMCSIdx; i++)
13091 {
13092 if (sinfo->signal <= rssiMcsTbl[mode][i])
13093 {
13094 maxMCSIdx = i;
13095 break;
13096 }
13097 }
13098 }
13099
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013100 if (rate_flags & eHAL_TX_RATE_VHT80)
13101 {
13102 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
13103 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
13104 }
13105 else if (rate_flags & eHAL_TX_RATE_VHT40)
13106 {
13107 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
13108 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
13109 }
13110 else if (rate_flags & eHAL_TX_RATE_VHT20)
13111 {
13112 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
13113 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
13114 }
13115
Leo Chang6f8870f2013-03-26 18:11:36 -070013116 maxSpeedMCS = 1;
13117 if (currentRate > maxRate)
13118 {
13119 maxRate = currentRate;
13120 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013121
Leo Chang6f8870f2013-03-26 18:11:36 -070013122 }
13123 else
13124#endif /* WLAN_FEATURE_11AC */
13125 {
13126 if (rate_flags & eHAL_TX_RATE_HT40)
13127 {
13128 rateFlag |= 1;
13129 }
13130 if (rate_flags & eHAL_TX_RATE_SGI)
13131 {
13132 rateFlag |= 2;
13133 }
13134
Girish Gowli01abcee2014-07-31 20:18:55 +053013135 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053013136 if (rssidx == 1 || rssidx == 2)
13137 {
13138 //get middle rate MCS index if rssi=1/2
13139 for (i=0; i <= 7; i++)
13140 {
13141 if (sinfo->signal <= rssiMcsTbl[mode][i])
13142 {
13143 temp = i+1;
13144 break;
13145 }
13146 }
13147 }
c_hpothu79aab322014-07-14 21:11:01 +053013148
13149 for (i = 0; i < MCSLeng; i++)
13150 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013151 for (j = 0; j < temp; j++)
13152 {
13153 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
13154 {
13155 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
13156 break;
13157 }
13158 }
13159 if ((j < temp) && (currentRate > maxRate))
13160 {
13161 maxRate = currentRate;
13162 maxSpeedMCS = 1;
13163 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
13164 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013165 }
13166 }
13167 }
13168
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013169 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
13170 {
13171 maxRate = myRate;
13172 maxSpeedMCS = 1;
13173 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13174 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013175 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053013176 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070013177 {
13178 maxRate = myRate;
13179 if (rate_flags & eHAL_TX_RATE_LEGACY)
13180 {
13181 maxSpeedMCS = 0;
13182 }
13183 else
13184 {
13185 maxSpeedMCS = 1;
13186 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13187 }
13188 }
13189
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013190 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070013191 {
13192 sinfo->txrate.legacy = maxRate;
13193#ifdef LINKSPEED_DEBUG_ENABLED
13194 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
13195#endif //LINKSPEED_DEBUG_ENABLED
13196 }
13197 else
13198 {
13199 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070013200#ifdef WLAN_FEATURE_11AC
13201 sinfo->txrate.nss = 1;
13202 if (rate_flags & eHAL_TX_RATE_VHT80)
13203 {
13204 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013205 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070013206 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013207 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070013208 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013209 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13210 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13211 }
13212 else if (rate_flags & eHAL_TX_RATE_VHT20)
13213 {
13214 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13215 }
13216#endif /* WLAN_FEATURE_11AC */
13217 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
13218 {
13219 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13220 if (rate_flags & eHAL_TX_RATE_HT40)
13221 {
13222 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13223 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013224 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013225 if (rate_flags & eHAL_TX_RATE_SGI)
13226 {
13227 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13228 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013229
Jeff Johnson295189b2012-06-20 16:38:30 -070013230#ifdef LINKSPEED_DEBUG_ENABLED
13231 pr_info("Reporting MCS rate %d flags %x\n",
13232 sinfo->txrate.mcs,
13233 sinfo->txrate.flags );
13234#endif //LINKSPEED_DEBUG_ENABLED
13235 }
13236 }
13237 else
13238 {
13239 // report current rate instead of max rate
13240
13241 if (rate_flags & eHAL_TX_RATE_LEGACY)
13242 {
13243 //provide to the UI in units of 100kbps
13244 sinfo->txrate.legacy = myRate;
13245#ifdef LINKSPEED_DEBUG_ENABLED
13246 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
13247#endif //LINKSPEED_DEBUG_ENABLED
13248 }
13249 else
13250 {
13251 //must be MCS
13252 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013253#ifdef WLAN_FEATURE_11AC
13254 sinfo->txrate.nss = 1;
13255 if (rate_flags & eHAL_TX_RATE_VHT80)
13256 {
13257 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13258 }
13259 else
13260#endif /* WLAN_FEATURE_11AC */
13261 {
13262 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13263 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013264 if (rate_flags & eHAL_TX_RATE_SGI)
13265 {
13266 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13267 }
13268 if (rate_flags & eHAL_TX_RATE_HT40)
13269 {
13270 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13271 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013272#ifdef WLAN_FEATURE_11AC
13273 else if (rate_flags & eHAL_TX_RATE_VHT80)
13274 {
13275 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
13276 }
13277#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070013278#ifdef LINKSPEED_DEBUG_ENABLED
13279 pr_info("Reporting actual MCS rate %d flags %x\n",
13280 sinfo->txrate.mcs,
13281 sinfo->txrate.flags );
13282#endif //LINKSPEED_DEBUG_ENABLED
13283 }
13284 }
13285 sinfo->filled |= STATION_INFO_TX_BITRATE;
13286
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013287 sinfo->tx_packets =
13288 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
13289 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
13290 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
13291 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
13292
13293 sinfo->tx_retries =
13294 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
13295 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
13296 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
13297 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
13298
13299 sinfo->tx_failed =
13300 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
13301 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
13302 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
13303 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
13304
13305 sinfo->filled |=
13306 STATION_INFO_TX_PACKETS |
13307 STATION_INFO_TX_RETRIES |
13308 STATION_INFO_TX_FAILED;
13309
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013310 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13311 TRACE_CODE_HDD_CFG80211_GET_STA,
13312 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013313 EXIT();
13314 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013315}
13316
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013317static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13318 u8* mac, struct station_info *sinfo)
13319{
13320 int ret;
13321
13322 vos_ssr_protect(__func__);
13323 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
13324 vos_ssr_unprotect(__func__);
13325
13326 return ret;
13327}
13328
13329static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070013330 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070013331{
13332 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013333 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013334 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013335 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013336
Jeff Johnsone7245742012-09-05 17:12:55 -070013337 ENTER();
13338
Jeff Johnson295189b2012-06-20 16:38:30 -070013339 if (NULL == pAdapter)
13340 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013341 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013342 return -ENODEV;
13343 }
13344
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013345 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13346 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
13347 pAdapter->sessionId, timeout));
13348
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013349 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013350 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013351 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013352 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013353 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013354 }
13355
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013356 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
13357 (TRUE == pHddCtx->hdd_wlan_suspended) &&
13358 (pHddCtx->cfg_ini->fhostArpOffload) &&
13359 (eConnectionState_Associated ==
13360 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13361 {
Amar Singhald53568e2013-09-26 11:03:45 -070013362
13363 hddLog(VOS_TRACE_LEVEL_INFO,
13364 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053013365 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013366 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13367 {
13368 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013369 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013370 __func__, vos_status);
13371 }
13372 }
13373
Jeff Johnson295189b2012-06-20 16:38:30 -070013374 /**The get power cmd from the supplicant gets updated by the nl only
13375 *on successful execution of the function call
13376 *we are oppositely mapped w.r.t mode in the driver
13377 **/
13378 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
13379
13380 if (VOS_STATUS_E_FAILURE == vos_status)
13381 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013382 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13383 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013384 return -EINVAL;
13385 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013386 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013387 return 0;
13388}
13389
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013390static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
13391 struct net_device *dev, bool mode, int timeout)
13392{
13393 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013394
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013395 vos_ssr_protect(__func__);
13396 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
13397 vos_ssr_unprotect(__func__);
13398
13399 return ret;
13400}
Jeff Johnson295189b2012-06-20 16:38:30 -070013401#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013402static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
13403 struct net_device *netdev,
13404 u8 key_index)
13405{
13406 ENTER();
13407 return 0;
13408}
13409
Jeff Johnson295189b2012-06-20 16:38:30 -070013410static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013411 struct net_device *netdev,
13412 u8 key_index)
13413{
13414 int ret;
13415 vos_ssr_protect(__func__);
13416 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
13417 vos_ssr_unprotect(__func__);
13418 return ret;
13419}
13420#endif //LINUX_VERSION_CODE
13421
13422#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13423static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13424 struct net_device *dev,
13425 struct ieee80211_txq_params *params)
13426{
13427 ENTER();
13428 return 0;
13429}
13430#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13431static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13432 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013433{
Jeff Johnsone7245742012-09-05 17:12:55 -070013434 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013435 return 0;
13436}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013437#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070013438
13439#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13440static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013441 struct net_device *dev,
13442 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013443{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013444 int ret;
13445
13446 vos_ssr_protect(__func__);
13447 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
13448 vos_ssr_unprotect(__func__);
13449 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013450}
13451#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13452static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
13453 struct ieee80211_txq_params *params)
13454{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013455 int ret;
13456
13457 vos_ssr_protect(__func__);
13458 ret = __wlan_hdd_set_txq_params(wiphy, params);
13459 vos_ssr_unprotect(__func__);
13460 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013461}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013462#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013463
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013464static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013465 struct net_device *dev,
13466 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070013467{
13468 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013469 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013470 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013471 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013472 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013473 v_CONTEXT_t pVosContext = NULL;
13474 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013475
Jeff Johnsone7245742012-09-05 17:12:55 -070013476 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013477
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013478 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070013479 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013480 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013481 return -EINVAL;
13482 }
13483
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013484 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13485 TRACE_CODE_HDD_CFG80211_DEL_STA,
13486 pAdapter->sessionId, pAdapter->device_mode));
13487
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013488 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13489 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013490 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013491 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013492 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013493 }
13494
Jeff Johnson295189b2012-06-20 16:38:30 -070013495 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013496 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013497 )
13498 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013499 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13500 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13501 if(pSapCtx == NULL){
13502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13503 FL("psapCtx is NULL"));
13504 return -ENOENT;
13505 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013506 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013507 {
13508 v_U16_t i;
13509 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13510 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013511 if ((pSapCtx->aStaInfo[i].isUsed) &&
13512 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070013513 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013514 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013515 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013516 ETHER_ADDR_LEN);
13517
Jeff Johnson295189b2012-06-20 16:38:30 -070013518 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013519 "%s: Delete STA with MAC::"
13520 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013521 __func__,
13522 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
13523 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013524 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013525 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013526 }
13527 }
13528 }
13529 else
13530 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013531
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013532 vos_status = hdd_softap_GetStaId(pAdapter,
13533 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013534 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13535 {
13536 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013537 "%s: Skip this DEL STA as this is not used::"
13538 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013539 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013540 return -ENOENT;
13541 }
13542
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013543 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013544 {
13545 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013546 "%s: Skip this DEL STA as deauth is in progress::"
13547 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013548 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013549 return -ENOENT;
13550 }
13551
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013552 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013553
Jeff Johnson295189b2012-06-20 16:38:30 -070013554 hddLog(VOS_TRACE_LEVEL_INFO,
13555 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013556 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013557 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013558 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013559
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013560 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013561 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13562 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013563 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013564 hddLog(VOS_TRACE_LEVEL_INFO,
13565 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013566 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013567 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013568 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013569 return -ENOENT;
13570 }
13571
Jeff Johnson295189b2012-06-20 16:38:30 -070013572 }
13573 }
13574
13575 EXIT();
13576
13577 return 0;
13578}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013579
13580#ifdef CFG80211_DEL_STA_V2
13581static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13582 struct net_device *dev,
13583 struct station_del_parameters *param)
13584#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013585static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13586 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013587#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013588{
13589 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013590 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070013591
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013592 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013593
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013594#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013595 if (NULL == param) {
13596 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013597 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013598 return -EINVAL;
13599 }
13600
13601 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
13602 param->subtype, &delStaParams);
13603
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013604#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053013605 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013606 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013607#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013608 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
13609
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013610 vos_ssr_unprotect(__func__);
13611
13612 return ret;
13613}
13614
13615static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013616 struct net_device *dev, u8 *mac, struct station_parameters *params)
13617{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013618 hdd_adapter_t *pAdapter;
13619 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013620 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013621#ifdef FEATURE_WLAN_TDLS
13622 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013623
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013624 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013625
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013626 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13627 if (NULL == pAdapter)
13628 {
13629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13630 "%s: Adapter is NULL",__func__);
13631 return -EINVAL;
13632 }
13633 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13634 status = wlan_hdd_validate_context(pHddCtx);
13635 if (0 != status)
13636 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013637 return status;
13638 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013639
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013640 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13641 TRACE_CODE_HDD_CFG80211_ADD_STA,
13642 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013643 mask = params->sta_flags_mask;
13644
13645 set = params->sta_flags_set;
13646
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053013647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013648 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
13649 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013650
13651 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13652 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013653 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013654 }
13655 }
13656#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013657 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013658 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013659}
13660
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013661static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
13662 struct net_device *dev, u8 *mac, struct station_parameters *params)
13663{
13664 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013665
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013666 vos_ssr_protect(__func__);
13667 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
13668 vos_ssr_unprotect(__func__);
13669
13670 return ret;
13671}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013672#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070013673
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013674static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070013675 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013676{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013677 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13678 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013679 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013680 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013681 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013682 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070013683
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013684 ENTER();
13685
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013686 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013687 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013688 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013689 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013690 return -EINVAL;
13691 }
13692
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013693 if (!pmksa) {
13694 hddLog(LOGE, FL("pmksa is NULL"));
13695 return -EINVAL;
13696 }
13697
13698 if (!pmksa->bssid || !pmksa->pmkid) {
13699 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
13700 pmksa->bssid, pmksa->pmkid);
13701 return -EINVAL;
13702 }
13703
13704 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
13705 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13706
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013707 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13708 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013709 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013710 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013711 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013712 }
13713
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013714 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013715 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13716
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013717 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
13718 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013719
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013720 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013721 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013722 &pmk_id, 1, FALSE);
13723
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013724 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13725 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
13726 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013727
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013728 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013729 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013730}
13731
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013732static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
13733 struct cfg80211_pmksa *pmksa)
13734{
13735 int ret;
13736
13737 vos_ssr_protect(__func__);
13738 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
13739 vos_ssr_unprotect(__func__);
13740
13741 return ret;
13742}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013743
Wilson Yang6507c4e2013-10-01 20:11:19 -070013744
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013745static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070013746 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013747{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013748 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13749 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013750 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013751 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013752
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013753 ENTER();
13754
Wilson Yang6507c4e2013-10-01 20:11:19 -070013755 /* Validate pAdapter */
13756 if (NULL == pAdapter)
13757 {
13758 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
13759 return -EINVAL;
13760 }
13761
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013762 if (!pmksa) {
13763 hddLog(LOGE, FL("pmksa is NULL"));
13764 return -EINVAL;
13765 }
13766
13767 if (!pmksa->bssid) {
13768 hddLog(LOGE, FL("pmksa->bssid is NULL"));
13769 return -EINVAL;
13770 }
13771
Kiet Lam98c46a12014-10-31 15:34:57 -070013772 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
13773 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13774
Wilson Yang6507c4e2013-10-01 20:11:19 -070013775 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13776 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070013777 if (0 != status)
13778 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070013779 return status;
13780 }
13781
13782 /*Retrieve halHandle*/
13783 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13784
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013785 /* Delete the PMKID CSR cache */
13786 if (eHAL_STATUS_SUCCESS !=
13787 sme_RoamDelPMKIDfromCache(halHandle,
13788 pAdapter->sessionId, pmksa->bssid, FALSE)) {
13789 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
13790 MAC_ADDR_ARRAY(pmksa->bssid));
13791 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013792 }
13793
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013794 EXIT();
13795 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013796}
13797
Wilson Yang6507c4e2013-10-01 20:11:19 -070013798
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013799static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
13800 struct cfg80211_pmksa *pmksa)
13801{
13802 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013803
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013804 vos_ssr_protect(__func__);
13805 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
13806 vos_ssr_unprotect(__func__);
13807
13808 return ret;
13809
13810}
13811
13812static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013813{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013814 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13815 tHalHandle halHandle;
13816 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013817 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013818
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013819 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070013820
13821 /* Validate pAdapter */
13822 if (NULL == pAdapter)
13823 {
13824 hddLog(VOS_TRACE_LEVEL_ERROR,
13825 "%s: Invalid Adapter" ,__func__);
13826 return -EINVAL;
13827 }
13828
13829 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13830 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070013831 if (0 != status)
13832 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070013833 return status;
13834 }
13835
13836 /*Retrieve halHandle*/
13837 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13838
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013839 /* Flush the PMKID cache in CSR */
13840 if (eHAL_STATUS_SUCCESS !=
13841 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
13842 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
13843 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013844 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013845 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080013846 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013847}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013848
13849static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
13850{
13851 int ret;
13852
13853 vos_ssr_protect(__func__);
13854 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
13855 vos_ssr_unprotect(__func__);
13856
13857 return ret;
13858}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013859#endif
13860
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013861#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013862static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13863 struct net_device *dev,
13864 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013865{
13866 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13867 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013868 hdd_context_t *pHddCtx;
13869 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013870
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013871 ENTER();
13872
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013873 if (NULL == pAdapter)
13874 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013875 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013876 return -ENODEV;
13877 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013878 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13879 ret = wlan_hdd_validate_context(pHddCtx);
13880 if (0 != ret)
13881 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013882 return ret;
13883 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013884 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013885 if (NULL == pHddStaCtx)
13886 {
13887 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
13888 return -EINVAL;
13889 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013890
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013891 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13892 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
13893 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013894 // Added for debug on reception of Re-assoc Req.
13895 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
13896 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013897 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013898 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080013899 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013900 }
13901
13902#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080013903 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013904 ftie->ie_len);
13905#endif
13906
13907 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013908 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13909 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013910 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013911
13912 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013913 return 0;
13914}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013915
13916static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13917 struct net_device *dev,
13918 struct cfg80211_update_ft_ies_params *ftie)
13919{
13920 int ret;
13921
13922 vos_ssr_protect(__func__);
13923 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
13924 vos_ssr_unprotect(__func__);
13925
13926 return ret;
13927}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013928#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013929
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013930#ifdef FEATURE_WLAN_SCAN_PNO
13931
13932void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
13933 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
13934{
13935 int ret;
13936 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
13937 hdd_context_t *pHddCtx;
13938
Nirav Shah80830bf2013-12-31 16:35:12 +053013939 ENTER();
13940
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013941 if (NULL == pAdapter)
13942 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013943 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013944 "%s: HDD adapter is Null", __func__);
13945 return ;
13946 }
13947
13948 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13949 if (NULL == pHddCtx)
13950 {
13951 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13952 "%s: HDD context is Null!!!", __func__);
13953 return ;
13954 }
13955
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013956 spin_lock(&pHddCtx->schedScan_lock);
13957 if (TRUE == pHddCtx->isWiphySuspended)
13958 {
13959 pHddCtx->isSchedScanUpdatePending = TRUE;
13960 spin_unlock(&pHddCtx->schedScan_lock);
13961 hddLog(VOS_TRACE_LEVEL_INFO,
13962 "%s: Update cfg80211 scan database after it resume", __func__);
13963 return ;
13964 }
13965 spin_unlock(&pHddCtx->schedScan_lock);
13966
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013967 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
13968
13969 if (0 > ret)
13970 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
13971
13972 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13974 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013975}
13976
13977/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013978 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013979 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013980 */
13981static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
13982{
13983 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13984 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013985 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013986 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13987 int status = 0;
13988 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13989
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013990 /* The current firmware design does not allow PNO during any
13991 * active sessions. Hence, determine the active sessions
13992 * and return a failure.
13993 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013994 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
13995 {
13996 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013997 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013998
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013999 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
14000 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
14001 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
14002 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
14003 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053014004 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014005 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014006 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014007 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014008 }
14009 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14010 pAdapterNode = pNext;
14011 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014012 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014013}
14014
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014015void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
14016{
14017 hdd_adapter_t *pAdapter = callbackContext;
14018 hdd_context_t *pHddCtx;
14019
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014020 ENTER();
14021
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014022 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
14023 {
14024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14025 FL("Invalid adapter or adapter has invalid magic"));
14026 return;
14027 }
14028
14029 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14030 if (0 != wlan_hdd_validate_context(pHddCtx))
14031 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014032 return;
14033 }
14034
c_hpothub53c45d2014-08-18 16:53:14 +053014035 if (VOS_STATUS_SUCCESS != status)
14036 {
14037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014038 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053014039 pHddCtx->isPnoEnable = FALSE;
14040 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014041
14042 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
14043 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014044 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014045}
14046
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014047/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014048 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
14049 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014050 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014051static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014052 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14053{
14054 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014055 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014056 hdd_context_t *pHddCtx;
14057 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014058 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053014059 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
14060 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014061 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14062 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014063 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014064 hdd_config_t *pConfig = NULL;
14065 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014066
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014067 ENTER();
14068
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014069 if (NULL == pAdapter)
14070 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014072 "%s: HDD adapter is Null", __func__);
14073 return -ENODEV;
14074 }
14075
14076 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014077 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014078
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014079 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014080 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014081 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014082 }
14083
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014084 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014085 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14086 if (NULL == hHal)
14087 {
14088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14089 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014090 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014091 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053014092 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014093 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053014094 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014095 {
14096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14097 "%s: aborting the existing scan is unsuccessfull", __func__);
14098 return -EBUSY;
14099 }
14100
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014101 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014102 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014104 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014105 return -EBUSY;
14106 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014107
c_hpothu37f21312014-04-09 21:49:54 +053014108 if (TRUE == pHddCtx->isPnoEnable)
14109 {
14110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14111 FL("already PNO is enabled"));
14112 return -EBUSY;
14113 }
c_hpothu225aa7c2014-10-22 17:45:13 +053014114
14115 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
14116 {
14117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14118 "%s: abort ROC failed ", __func__);
14119 return -EBUSY;
14120 }
14121
c_hpothu37f21312014-04-09 21:49:54 +053014122 pHddCtx->isPnoEnable = TRUE;
14123
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014124 pnoRequest.enable = 1; /*Enable PNO */
14125 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014126
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014127 if (( !pnoRequest.ucNetworksCount ) ||
14128 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014129 {
14130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014131 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014132 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014133 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014134 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014135 goto error;
14136 }
14137
14138 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
14139 {
14140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014141 "%s: Incorrect number of channels %d",
14142 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014143 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014144 goto error;
14145 }
14146
14147 /* Framework provides one set of channels(all)
14148 * common for all saved profile */
14149 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14150 channels_allowed, &num_channels_allowed))
14151 {
14152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14153 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014154 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014155 goto error;
14156 }
14157 /* Checking each channel against allowed channel list */
14158 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053014159 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014160 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014161 char chList [(request->n_channels*5)+1];
14162 int len;
14163 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014164 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014165 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014166 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014167 if (request->channels[i]->hw_value == channels_allowed[indx])
14168 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014169 if ((!pConfig->enableDFSPnoChnlScan) &&
14170 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
14171 {
14172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14173 "%s : Dropping DFS channel : %d",
14174 __func__,channels_allowed[indx]);
14175 num_ignore_dfs_ch++;
14176 break;
14177 }
14178
Nirav Shah80830bf2013-12-31 16:35:12 +053014179 valid_ch[num_ch++] = request->channels[i]->hw_value;
14180 len += snprintf(chList+len, 5, "%d ",
14181 request->channels[i]->hw_value);
14182 break ;
14183 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014184 }
14185 }
Nirav Shah80830bf2013-12-31 16:35:12 +053014186 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014187
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014188 /*If all channels are DFS and dropped, then ignore the PNO request*/
14189 if (num_ignore_dfs_ch == request->n_channels)
14190 {
14191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14192 "%s : All requested channels are DFS channels", __func__);
14193 ret = -EINVAL;
14194 goto error;
14195 }
14196 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014197
14198 pnoRequest.aNetworks =
14199 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14200 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014201 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014202 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14203 FL("failed to allocate memory aNetworks %u"),
14204 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14205 goto error;
14206 }
14207 vos_mem_zero(pnoRequest.aNetworks,
14208 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14209
14210 /* Filling per profile params */
14211 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
14212 {
14213 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014214 request->match_sets[i].ssid.ssid_len;
14215
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014216 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
14217 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014218 {
14219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014220 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014221 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014222 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014223 goto error;
14224 }
14225
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014226 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014227 request->match_sets[i].ssid.ssid,
14228 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014229 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14230 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014231 i, pnoRequest.aNetworks[i].ssId.ssId);
14232 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
14233 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
14234 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014235
14236 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014237 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
14238 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014239
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014240 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014241 }
14242
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014243 for (i = 0; i < request->n_ssids; i++)
14244 {
14245 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014246 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014247 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014248 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014249 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014250 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014251 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014252 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014253 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014254 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014255 break;
14256 }
14257 j++;
14258 }
14259 }
14260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14261 "Number of hidden networks being Configured = %d",
14262 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080014264 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014265
14266 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14267 if (pnoRequest.p24GProbeTemplate == NULL)
14268 {
14269 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14270 FL("failed to allocate memory p24GProbeTemplate %u"),
14271 SIR_PNO_MAX_PB_REQ_SIZE);
14272 goto error;
14273 }
14274
14275 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14276 if (pnoRequest.p5GProbeTemplate == NULL)
14277 {
14278 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14279 FL("failed to allocate memory p5GProbeTemplate %u"),
14280 SIR_PNO_MAX_PB_REQ_SIZE);
14281 goto error;
14282 }
14283
14284 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14285 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14286
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053014287 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
14288 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014289 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014290 pnoRequest.us24GProbeTemplateLen = request->ie_len;
14291 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
14292 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014293
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014294 pnoRequest.us5GProbeTemplateLen = request->ie_len;
14295 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
14296 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014297 }
14298
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014299 /* Driver gets only one time interval which is hardcoded in
14300 * supplicant for 10000ms. Taking power consumption into account 6 timers
14301 * will be used, Timervalue is increased exponentially i.e 10,20,40,
14302 * 80,160,320 secs. And number of scan cycle for each timer
14303 * is configurable through INI param gPNOScanTimerRepeatValue.
14304 * If it is set to 0 only one timer will be used and PNO scan cycle
14305 * will be repeated after each interval specified by supplicant
14306 * till PNO is disabled.
14307 */
14308 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014309 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014310 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014311 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014312 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
14313
14314 tempInterval = (request->interval)/1000;
14315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14316 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
14317 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014318 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014319 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014320 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014321 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014322 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014323 tempInterval *= 2;
14324 }
14325 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014326 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014327
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014328 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014329
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014330 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014331 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
14332 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014333 pAdapter->pno_req_status = 0;
14334
Nirav Shah80830bf2013-12-31 16:35:12 +053014335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14336 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014337 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
14338 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053014339
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014340 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014341 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014342 hdd_cfg80211_sched_scan_done_callback, pAdapter);
14343 if (eHAL_STATUS_SUCCESS != status)
14344 {
14345 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014346 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014347 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014348 goto error;
14349 }
14350
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014351 ret = wait_for_completion_timeout(
14352 &pAdapter->pno_comp_var,
14353 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
14354 if (0 >= ret)
14355 {
14356 // Did not receive the response for PNO enable in time.
14357 // Assuming the PNO enable was success.
14358 // Returning error from here, because we timeout, results
14359 // in side effect of Wifi (Wifi Setting) not to work.
14360 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14361 FL("Timed out waiting for PNO to be Enabled"));
14362 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014363 }
14364
14365 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053014366 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014367
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014368error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14370 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053014371 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014372 if (pnoRequest.aNetworks)
14373 vos_mem_free(pnoRequest.aNetworks);
14374 if (pnoRequest.p24GProbeTemplate)
14375 vos_mem_free(pnoRequest.p24GProbeTemplate);
14376 if (pnoRequest.p5GProbeTemplate)
14377 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014378
14379 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014380 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014381}
14382
14383/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014384 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
14385 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014386 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014387static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
14388 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14389{
14390 int ret;
14391
14392 vos_ssr_protect(__func__);
14393 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
14394 vos_ssr_unprotect(__func__);
14395
14396 return ret;
14397}
14398
14399/*
14400 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
14401 * Function to disable PNO
14402 */
14403static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014404 struct net_device *dev)
14405{
14406 eHalStatus status = eHAL_STATUS_FAILURE;
14407 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14408 hdd_context_t *pHddCtx;
14409 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014410 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014411 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014412
14413 ENTER();
14414
14415 if (NULL == pAdapter)
14416 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014418 "%s: HDD adapter is Null", __func__);
14419 return -ENODEV;
14420 }
14421
14422 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014423
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014424 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014425 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014427 "%s: HDD context is Null", __func__);
14428 return -ENODEV;
14429 }
14430
14431 /* The return 0 is intentional when isLogpInProgress and
14432 * isLoadUnloadInProgress. We did observe a crash due to a return of
14433 * failure in sched_scan_stop , especially for a case where the unload
14434 * of the happens at the same time. The function __cfg80211_stop_sched_scan
14435 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
14436 * success. If it returns a failure , then its next invocation due to the
14437 * clean up of the second interface will have the dev pointer corresponding
14438 * to the first one leading to a crash.
14439 */
14440 if (pHddCtx->isLogpInProgress)
14441 {
14442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14443 "%s: LOGP in Progress. Ignore!!!", __func__);
14444 return ret;
14445 }
14446
Mihir Shete18156292014-03-11 15:38:30 +053014447 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014448 {
14449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14450 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14451 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014452 }
14453
14454 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14455 if (NULL == hHal)
14456 {
14457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14458 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014459 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014460 }
14461
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014462 pnoRequest.enable = 0; /* Disable PNO */
14463 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014464
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014465 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014466 pAdapter->sessionId,
14467 NULL, pAdapter);
14468 if (eHAL_STATUS_SUCCESS != status)
14469 {
14470 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14471 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014472 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014473 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014474 }
c_hpothu37f21312014-04-09 21:49:54 +053014475 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014476
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014477error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014478 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014479 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014480
14481 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014482 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014483}
14484
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014485/*
14486 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
14487 * NL interface to disable PNO
14488 */
14489static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
14490 struct net_device *dev)
14491{
14492 int ret;
14493
14494 vos_ssr_protect(__func__);
14495 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
14496 vos_ssr_unprotect(__func__);
14497
14498 return ret;
14499}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014500#endif /*FEATURE_WLAN_SCAN_PNO*/
14501
14502
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014503#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014504#if TDLS_MGMT_VERSION2
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014505static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014506 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014507 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
14508#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014509static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014510 u8 *peer, u8 action_code, u8 dialog_token,
14511 u16 status_code, const u8 *buf, size_t len)
14512#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014513{
14514
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014515 hdd_adapter_t *pAdapter;
14516 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014517 u8 peerMac[6];
14518 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070014519 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080014520 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070014521 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014522 int ret;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014523#if !(TDLS_MGMT_VERSION2)
14524 u32 peer_capability = 0;
14525#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014526 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014527
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014528 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14529 if (NULL == pAdapter)
14530 {
14531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14532 "%s: Adapter is NULL",__func__);
14533 return -EINVAL;
14534 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014535 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14536 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
14537 pAdapter->sessionId, action_code));
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014538 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014539 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014540 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014541 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014542 "Invalid arguments");
14543 return -EINVAL;
14544 }
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014545 if (pHddCtx->isLogpInProgress)
14546 {
14547 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14548 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053014549 wlan_hdd_tdls_set_link_status(pAdapter,
14550 peer,
14551 eTDLS_LINK_IDLE,
14552 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014553 return -EBUSY;
14554 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014555 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
14556 {
14557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14558 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14559 return -EAGAIN;
14560 }
Hoonki Lee27511902013-03-14 18:19:06 -070014561 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014562 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070014564 "%s: TDLS mode is disabled OR not enabled in FW."
14565 MAC_ADDRESS_STR " action %d declined.",
14566 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014567 return -ENOTSUPP;
14568 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014569
Hoonki Lee27511902013-03-14 18:19:06 -070014570 /* other than teardown frame, other mgmt frames are not sent if disabled */
14571 if (SIR_MAC_TDLS_TEARDOWN != action_code)
14572 {
14573 /* if tdls_mode is disabled to respond to peer's request */
14574 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
14575 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070014577 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014578 " TDLS mode is disabled. action %d declined.",
14579 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070014580
14581 return -ENOTSUPP;
14582 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014583
14584 if (vos_max_concurrent_connections_reached())
14585 {
14586 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14587 return -EINVAL;
14588 }
Hoonki Lee27511902013-03-14 18:19:06 -070014589 }
14590
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014591 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
14592 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053014593 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014594 {
14595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014596 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014597 " TDLS setup is ongoing. action %d declined.",
14598 __func__, MAC_ADDR_ARRAY(peer), action_code);
14599 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014600 }
14601 }
14602
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014603 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
14604 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080014605 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014606 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14607 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014608 {
14609 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
14610 we return error code at 'add_station()'. Hence we have this
14611 check again in addtion to add_station().
14612 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014613 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014614 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014615 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14616 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014617 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
14618 __func__, MAC_ADDR_ARRAY(peer), action_code,
14619 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053014620 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080014621 }
14622 else
14623 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014624 /* maximum reached. tweak to send error code to peer and return
14625 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014626 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14628 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014629 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
14630 __func__, MAC_ADDR_ARRAY(peer), status_code,
14631 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070014632 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014633 /* fall through to send setup resp with failure status
14634 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014635 }
14636 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014637 else
14638 {
14639 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014640 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014641 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014642 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014644 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
14645 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014646 return -EPERM;
14647 }
14648 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014649 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014650 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014651
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014653 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014654 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
14655 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014656
Hoonki Leea34dd892013-02-05 22:56:02 -080014657 /*Except teardown responder will not be used so just make 0*/
14658 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014659 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080014660 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014661
14662 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014663 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014664
14665 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
14666 responder = pTdlsPeer->is_responder;
14667 else
Hoonki Leea34dd892013-02-05 22:56:02 -080014668 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014669 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014670 "%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 -070014671 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
14672 dialog_token, status_code, len);
14673 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080014674 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014675 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014676
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014677 /* For explicit trigger of DIS_REQ come out of BMPS for
14678 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070014679 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014680 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
14681 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070014682 {
14683 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
14684 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014686 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014687 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
14688 if (status != VOS_STATUS_SUCCESS) {
14689 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
14690 }
Hoonki Lee14621352013-04-16 17:51:19 -070014691 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014692 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
14693 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED)) {
14694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
14695 }
14696 }
Hoonki Lee14621352013-04-16 17:51:19 -070014697 }
14698
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014699 /* make sure doesn't call send_mgmt() while it is pending */
14700 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
14701 {
14702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014703 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014704 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014705 ret = -EBUSY;
14706 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014707 }
14708
14709 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014710 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
14711
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014712 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053014713 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014714
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014715 if (VOS_STATUS_SUCCESS != status)
14716 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14718 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014719 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014720 ret = -EINVAL;
14721 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014722 }
14723
Hoonki Leed37cbb32013-04-20 00:31:14 -070014724 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
14725 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
14726
14727 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014728 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070014729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014730 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070014731 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014732 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080014733
14734 if (pHddCtx->isLogpInProgress)
14735 {
14736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14737 "%s: LOGP in Progress. Ignore!!!", __func__);
14738 return -EAGAIN;
14739 }
14740
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014741 ret = -EINVAL;
14742 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014743 }
14744
Gopichand Nakkala05922802013-03-14 12:23:19 -070014745 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070014746 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014747 ret = max_sta_failed;
14748 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070014749 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014750
Hoonki Leea34dd892013-02-05 22:56:02 -080014751 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
14752 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014753 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE)) {
14754 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
14755 }
Hoonki Leea34dd892013-02-05 22:56:02 -080014756 }
14757 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
14758 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014759 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE)) {
14760 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
14761 }
Hoonki Leea34dd892013-02-05 22:56:02 -080014762 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014763
14764 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014765
14766tx_failed:
14767 /* add_station will be called before sending TDLS_SETUP_REQ and
14768 * TDLS_SETUP_RSP and as part of add_station driver will enable
14769 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
14770 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
14771 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
14772 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
14773 */
14774
14775 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
14776 (SIR_MAC_TDLS_SETUP_RSP == action_code))
14777 wlan_hdd_tdls_check_bmps(pAdapter);
14778 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014779}
14780
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014781#if TDLS_MGMT_VERSION2
14782static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14783 u8 *peer, u8 action_code, u8 dialog_token,
14784 u16 status_code, u32 peer_capability,
14785 const u8 *buf, size_t len)
14786#else
14787static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14788 u8 *peer, u8 action_code, u8 dialog_token,
14789 u16 status_code, const u8 *buf, size_t len)
14790#endif
14791{
14792 int ret;
14793
14794 vos_ssr_protect(__func__);
14795#if TDLS_MGMT_VERSION2
14796 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14797 status_code, peer_capability, buf, len);
14798#else
14799 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14800 status_code, buf, len);
14801#endif
14802 vos_ssr_unprotect(__func__);
14803
14804 return ret;
14805}
Atul Mittal115287b2014-07-08 13:26:33 +053014806
14807int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
14808 u8 *peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014809 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053014810 cfg80211_exttdls_callback callback)
14811{
14812
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014813 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053014814 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014815 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053014816 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14817 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
14818 __func__, MAC_ADDR_ARRAY(peer));
14819
14820 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14821 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14822
14823 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014824 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
14825 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
14826 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053014827 return -ENOTSUPP;
14828 }
14829
14830 /* To cater the requirement of establishing the TDLS link
14831 * irrespective of the data traffic , get an entry of TDLS peer.
14832 */
14833 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
14834 if (pTdlsPeer == NULL) {
14835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14836 "%s: peer " MAC_ADDRESS_STR " not existing",
14837 __func__, MAC_ADDR_ARRAY(peer));
14838 return -EINVAL;
14839 }
14840
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053014841 /* check FW TDLS Off Channel capability */
14842 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
14843 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014844 {
14845 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
14846 pTdlsPeer->peerParams.global_operating_class =
14847 tdls_peer_params->global_operating_class;
14848 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
14849 pTdlsPeer->peerParams.min_bandwidth_kbps =
14850 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014851 /* check configured channel is valid, non dfs and
14852 * not current operating channel */
14853 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
14854 tdls_peer_params->channel)) &&
14855 (pHddStaCtx) &&
14856 (tdls_peer_params->channel !=
14857 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014858 {
14859 pTdlsPeer->isOffChannelConfigured = TRUE;
14860 }
14861 else
14862 {
14863 pTdlsPeer->isOffChannelConfigured = FALSE;
14864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14865 "%s: Configured Tdls Off Channel is not valid", __func__);
14866
14867 }
14868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014869 "%s: tdls_off_channel %d isOffChannelConfigured %d "
14870 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014871 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014872 pTdlsPeer->isOffChannelConfigured,
14873 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014874 }
14875 else
14876 {
14877 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053014878 "%s: TDLS off channel FW capability %d or "
14879 "Invalid TDLS Peer Params", __func__,
14880 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014881 }
14882
Atul Mittal115287b2014-07-08 13:26:33 +053014883 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
14884
14885 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14886 " %s TDLS Add Force Peer Failed",
14887 __func__);
14888 return -EINVAL;
14889 }
14890 /*EXT TDLS*/
14891
14892 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
14893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14894 " %s TDLS set callback Failed",
14895 __func__);
14896 return -EINVAL;
14897 }
14898
14899 return(0);
14900
14901}
14902
14903int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
14904{
14905
14906 hddTdlsPeer_t *pTdlsPeer;
14907 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14909 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
14910 __func__, MAC_ADDR_ARRAY(peer));
14911
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014912 if (0 != wlan_hdd_validate_context(pHddCtx)) {
14913 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
14914 return -EINVAL;
14915 }
14916
Atul Mittal115287b2014-07-08 13:26:33 +053014917 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14918 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14919
14920 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014921 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
14922 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
14923 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053014924 return -ENOTSUPP;
14925 }
14926
14927
14928 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14929
14930 if ( NULL == pTdlsPeer ) {
14931 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
14932 " peer not exsting",
14933 __func__, MAC_ADDR_ARRAY(peer));
14934 return -EINVAL;
14935 }
14936 else {
14937 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
14938 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014939 /* if channel switch is configured, reset
14940 the channel for this peer */
14941 if (TRUE == pTdlsPeer->isOffChannelConfigured)
14942 {
14943 pTdlsPeer->peerParams.channel = 0;
14944 pTdlsPeer->isOffChannelConfigured = FALSE;
14945 }
Atul Mittal115287b2014-07-08 13:26:33 +053014946 }
14947
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014948 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
14949 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053014950 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014951 }
Atul Mittal115287b2014-07-08 13:26:33 +053014952
14953 /*EXT TDLS*/
14954
14955 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
14956
14957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14958 " %s TDLS set callback Failed",
14959 __func__);
14960 return -EINVAL;
14961 }
14962 return(0);
14963
14964}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014965static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014966 u8 *peer, enum nl80211_tdls_operation oper)
14967{
14968 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14969 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014970 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014971 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014972
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014973 ENTER();
14974
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014975 if (!pAdapter) {
14976 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
14977 return -EINVAL;
14978 }
14979
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014980 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14981 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
14982 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014983 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014984 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014986 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014987 return -EINVAL;
14988 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014989
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014990 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014991 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014992 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014993 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014994 }
14995
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014996
14997 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014998 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014999 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015001 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
15002 "Cannot process TDLS commands",
15003 pHddCtx->cfg_ini->fEnableTDLSSupport,
15004 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015005 return -ENOTSUPP;
15006 }
15007
15008 switch (oper) {
15009 case NL80211_TDLS_ENABLE_LINK:
15010 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015011 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015012 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015013 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053015014 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015015 tANI_U16 numCurrTdlsPeers = 0;
15016 hddTdlsPeer_t *connPeer = NULL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015017
Sunil Dutt41de4e22013-11-14 18:09:02 +053015018 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015019 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015020 if ( NULL == pTdlsPeer ) {
15021 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15022 " (oper %d) not exsting. ignored",
15023 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15024 return -EINVAL;
15025 }
15026
15027 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15028 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15029 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15030 "NL80211_TDLS_ENABLE_LINK");
15031
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070015032 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
15033 {
15034 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
15035 MAC_ADDRESS_STR " failed",
15036 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
15037 return -EINVAL;
15038 }
15039
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015040 /* TDLS Off Channel, Disable tdls channel switch,
15041 when there are more than one tdls link */
15042 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053015043 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015044 {
15045 /* get connected peer and send disable tdls off chan */
15046 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
15047 if (connPeer && (connPeer->isOffChannelConfigured == TRUE))
15048 {
15049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15050 "%s: More then one peer connected, Disable "
15051 "TDLS channel switch", __func__);
15052
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015053 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015054 ret = sme_SendTdlsChanSwitchReq(
15055 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015056 pAdapter->sessionId,
15057 connPeer->peerMac,
15058 connPeer->peerParams.channel,
15059 TDLS_OFF_CHANNEL_BW_OFFSET,
15060 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015061 if (ret != VOS_STATUS_SUCCESS) {
15062 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel request"));
15063 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015064 }
15065 else
15066 {
15067 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15068 "%s: No TDLS Connected Peer or "
15069 "isOffChannelConfigured %d",
15070 __func__,
15071 (connPeer ? connPeer->isOffChannelConfigured : -1));
15072 }
15073 }
15074
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015075 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015076 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015077 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053015078
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015079 if (0 != wlan_hdd_tdls_get_link_establish_params(
15080 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015081 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015082 return -EINVAL;
15083 }
15084 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015085
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015086 ret = sme_SendTdlsLinkEstablishParams(
15087 WLAN_HDD_GET_HAL_CTX(pAdapter),
15088 pAdapter->sessionId, peer,
15089 &tdlsLinkEstablishParams);
15090 if (ret != VOS_STATUS_SUCCESS) {
15091 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
15092 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015093 /* Send TDLS peer UAPSD capabilities to the firmware and
15094 * register with the TL on after the response for this operation
15095 * is received .
15096 */
15097 ret = wait_for_completion_interruptible_timeout(
15098 &pAdapter->tdls_link_establish_req_comp,
15099 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
15100 if (ret <= 0)
15101 {
15102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15103 "%s: Link Establish Request Faled Status %ld",
15104 __func__, ret);
15105 return -EINVAL;
15106 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015107 }
Atul Mittal115287b2014-07-08 13:26:33 +053015108 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15109 eTDLS_LINK_CONNECTED,
15110 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015111 staDesc.ucSTAId = pTdlsPeer->staId;
15112 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015113 ret = WLANTL_UpdateTdlsSTAClient(
15114 pHddCtx->pvosContext,
15115 &staDesc);
15116 if (ret != VOS_STATUS_SUCCESS) {
15117 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
15118 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053015119
Gopichand Nakkala471708b2013-06-04 20:03:01 +053015120 /* Mark TDLS client Authenticated .*/
15121 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
15122 pTdlsPeer->staId,
15123 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015124 if (VOS_STATUS_SUCCESS == status)
15125 {
Hoonki Lee14621352013-04-16 17:51:19 -070015126 if (pTdlsPeer->is_responder == 0)
15127 {
15128 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
15129
15130 wlan_hdd_tdls_timer_restart(pAdapter,
15131 &pTdlsPeer->initiatorWaitTimeoutTimer,
15132 WAIT_TIME_TDLS_INITIATOR);
15133 /* suspend initiator TX until it receives direct packet from the
15134 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015135 ret = WLANTL_SuspendDataTx(
15136 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15137 &staId, NULL);
15138 if (ret != VOS_STATUS_SUCCESS) {
15139 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
15140 }
Hoonki Lee14621352013-04-16 17:51:19 -070015141 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015142
15143 /* TDLS Off Channel, Enable tdls channel switch,
15144 when their is only one tdls link and it supports */
15145 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15146 if ((numCurrTdlsPeers == 1) &&
15147 (TRUE == pTdlsPeer->isOffChannelSupported) &&
15148 (TRUE == pTdlsPeer->isOffChannelConfigured))
15149 {
15150 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15151 "%s: Send TDLS channel switch request for channel %d",
15152 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015153
15154 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015155 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
15156 pAdapter->sessionId,
15157 pTdlsPeer->peerMac,
15158 pTdlsPeer->peerParams.channel,
15159 TDLS_OFF_CHANNEL_BW_OFFSET,
15160 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015161 if (ret != VOS_STATUS_SUCCESS) {
15162 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
15163 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015164 }
15165 else
15166 {
15167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15168 "%s: TDLS channel switch request not sent"
15169 " numCurrTdlsPeers %d "
15170 "isOffChannelSupported %d "
15171 "isOffChannelConfigured %d",
15172 __func__, numCurrTdlsPeers,
15173 pTdlsPeer->isOffChannelSupported,
15174 pTdlsPeer->isOffChannelConfigured);
15175 }
15176
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015177 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015178 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015179
15180 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015181 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
15182 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015183 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015184 int ac;
15185 uint8 ucAc[4] = { WLANTL_AC_VO,
15186 WLANTL_AC_VI,
15187 WLANTL_AC_BK,
15188 WLANTL_AC_BE };
15189 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
15190 for(ac=0; ac < 4; ac++)
15191 {
15192 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15193 pTdlsPeer->staId, ucAc[ac],
15194 tlTid[ac], tlTid[ac], 0, 0,
15195 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015196 if (status != VOS_STATUS_SUCCESS) {
15197 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
15198 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015199 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015200 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015201 }
15202
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015203 }
15204 break;
15205 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080015206 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015207 tANI_U16 numCurrTdlsPeers = 0;
15208 hddTdlsPeer_t *connPeer = NULL;
15209
Sunil Dutt41de4e22013-11-14 18:09:02 +053015210 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15211
15212 if ( NULL == pTdlsPeer ) {
15213 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15214 " (oper %d) not exsting. ignored",
15215 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15216 return -EINVAL;
15217 }
15218
15219 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15220 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15221 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15222 "NL80211_TDLS_DISABLE_LINK");
15223
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015224 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080015225 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015226 long status;
15227
Atul Mittal271a7652014-09-12 13:18:22 +053015228
15229 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15230 eTDLS_LINK_TEARING,
15231 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
15232 eTDLS_LINK_UNSPECIFIED:
15233 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015234 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
15235
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015236 status = sme_DeleteTdlsPeerSta(
15237 WLAN_HDD_GET_HAL_CTX(pAdapter),
15238 pAdapter->sessionId, peer );
15239 if (status != VOS_STATUS_SUCCESS) {
15240 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15241 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015242
15243 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
15244 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053015245 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053015246 eTDLS_LINK_IDLE,
15247 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015248 if (status <= 0)
15249 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015250 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15251 "%s: Del station failed status %ld",
15252 __func__, status);
15253 return -EPERM;
15254 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015255
15256 /* TDLS Off Channel, Enable tdls channel switch,
15257 when their is only one tdls link and it supports */
15258 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15259 if (numCurrTdlsPeers == 1)
15260 {
15261 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
15262 if ((connPeer) &&
15263 (connPeer->isOffChannelSupported == TRUE) &&
15264 (connPeer->isOffChannelConfigured == TRUE))
15265 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015266 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015267 status = sme_SendTdlsChanSwitchReq(
15268 WLAN_HDD_GET_HAL_CTX(pAdapter),
15269 pAdapter->sessionId,
15270 connPeer->peerMac,
15271 connPeer->peerParams.channel,
15272 TDLS_OFF_CHANNEL_BW_OFFSET,
15273 TDLS_CHANNEL_SWITCH_ENABLE);
15274 if (status != VOS_STATUS_SUCCESS) {
15275 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
15276 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015277 }
15278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15279 "%s: TDLS channel switch "
15280 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015281 "isOffChannelConfigured %d "
15282 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015283 __func__,
15284 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015285 (connPeer ? connPeer->isOffChannelConfigured : -1),
15286 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015287 }
15288 else
15289 {
15290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15291 "%s: TDLS channel switch request not sent "
15292 "numCurrTdlsPeers %d ",
15293 __func__, numCurrTdlsPeers);
15294 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015295 }
15296 else
15297 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15299 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080015300 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015301 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015302 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015303 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015304 {
Atul Mittal115287b2014-07-08 13:26:33 +053015305 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015306
Atul Mittal115287b2014-07-08 13:26:33 +053015307 if (0 != status)
15308 {
15309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15310 "%s: Error in TDLS Teardown", __func__);
15311 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015312 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053015313 break;
15314 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015315 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015316 {
Atul Mittal115287b2014-07-08 13:26:33 +053015317 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
15318 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015319 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053015320 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015321
Atul Mittal115287b2014-07-08 13:26:33 +053015322 if (0 != status)
15323 {
15324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15325 "%s: Error in TDLS Setup", __func__);
15326 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053015327 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053015328 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015329 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015330 case NL80211_TDLS_DISCOVERY_REQ:
15331 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15333 "%s: We don't support in-driver setup/teardown/discovery "
15334 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015335 return -ENOTSUPP;
15336 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15338 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015339 return -ENOTSUPP;
15340 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015341
15342 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015343 return 0;
15344}
Chilam NG571c65a2013-01-19 12:27:36 +053015345
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015346static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
15347 u8 *peer, enum nl80211_tdls_operation oper)
15348{
15349 int ret;
15350
15351 vos_ssr_protect(__func__);
15352 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
15353 vos_ssr_unprotect(__func__);
15354
15355 return ret;
15356}
15357
Chilam NG571c65a2013-01-19 12:27:36 +053015358int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
15359 struct net_device *dev, u8 *peer)
15360{
Arif Hussaina7c8e412013-11-20 11:06:42 -080015361 hddLog(VOS_TRACE_LEVEL_INFO,
15362 "tdls send discover req: "MAC_ADDRESS_STR,
15363 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053015364
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015365#if TDLS_MGMT_VERSION2
15366 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15367 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15368#else
Chilam NG571c65a2013-01-19 12:27:36 +053015369 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15370 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015371#endif
Chilam NG571c65a2013-01-19 12:27:36 +053015372}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015373#endif
15374
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015375#ifdef WLAN_FEATURE_GTK_OFFLOAD
15376/*
15377 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
15378 * Callback rountine called upon receiving response for
15379 * get offload info
15380 */
15381void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
15382 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
15383{
15384
15385 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015386 tANI_U8 tempReplayCounter[8];
15387 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015388
15389 ENTER();
15390
15391 if (NULL == pAdapter)
15392 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053015393 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015394 "%s: HDD adapter is Null", __func__);
15395 return ;
15396 }
15397
15398 if (NULL == pGtkOffloadGetInfoRsp)
15399 {
15400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15401 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
15402 return ;
15403 }
15404
15405 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
15406 {
15407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15408 "%s: wlan Failed to get replay counter value",
15409 __func__);
15410 return ;
15411 }
15412
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015413 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15414 /* Update replay counter */
15415 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
15416 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15417
15418 {
15419 /* changing from little to big endian since supplicant
15420 * works on big endian format
15421 */
15422 int i;
15423 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15424
15425 for (i = 0; i < 8; i++)
15426 {
15427 tempReplayCounter[7-i] = (tANI_U8)p[i];
15428 }
15429 }
15430
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015431 /* Update replay counter to NL */
15432 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015433 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015434}
15435
15436/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015437 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015438 * This function is used to offload GTK rekeying job to the firmware.
15439 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015440int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015441 struct cfg80211_gtk_rekey_data *data)
15442{
15443 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15444 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15445 hdd_station_ctx_t *pHddStaCtx;
15446 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015447 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015448 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015449 eHalStatus status = eHAL_STATUS_FAILURE;
15450
15451 ENTER();
15452
15453 if (NULL == pAdapter)
15454 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015456 "%s: HDD adapter is Null", __func__);
15457 return -ENODEV;
15458 }
15459
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015460 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15461 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
15462 pAdapter->sessionId, pAdapter->device_mode));
15463
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015464 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015465 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015466 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015467 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015468 }
15469
15470 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15471 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15472 if (NULL == hHal)
15473 {
15474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15475 "%s: HAL context is Null!!!", __func__);
15476 return -EAGAIN;
15477 }
15478
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015479 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
15480 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
15481 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
15482 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015483 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015484 {
15485 /* changing from big to little endian since driver
15486 * works on little endian format
15487 */
15488 tANI_U8 *p =
15489 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
15490 int i;
15491
15492 for (i = 0; i < 8; i++)
15493 {
15494 p[7-i] = data->replay_ctr[i];
15495 }
15496 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015497
15498 if (TRUE == pHddCtx->hdd_wlan_suspended)
15499 {
15500 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015501 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
15502 sizeof (tSirGtkOffloadParams));
15503 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015504 pAdapter->sessionId);
15505
15506 if (eHAL_STATUS_SUCCESS != status)
15507 {
15508 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15509 "%s: sme_SetGTKOffload failed, returned %d",
15510 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053015511
15512 /* Need to clear any trace of key value in the memory.
15513 * Thus zero out the memory even though it is local
15514 * variable.
15515 */
15516 vos_mem_zero(&hddGtkOffloadReqParams,
15517 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015518 return status;
15519 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015520 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15521 "%s: sme_SetGTKOffload successfull", __func__);
15522 }
15523 else
15524 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15526 "%s: wlan not suspended GTKOffload request is stored",
15527 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015528 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015529
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053015530 /* Need to clear any trace of key value in the memory.
15531 * Thus zero out the memory even though it is local
15532 * variable.
15533 */
15534 vos_mem_zero(&hddGtkOffloadReqParams,
15535 sizeof(hddGtkOffloadReqParams));
15536
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015537 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015538 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015539}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015540
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015541int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
15542 struct cfg80211_gtk_rekey_data *data)
15543{
15544 int ret;
15545
15546 vos_ssr_protect(__func__);
15547 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
15548 vos_ssr_unprotect(__func__);
15549
15550 return ret;
15551}
15552#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015553/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015554 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015555 * This function is used to set access control policy
15556 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015557static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15558 struct net_device *dev,
15559 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015560{
15561 int i;
15562 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15563 hdd_hostapd_state_t *pHostapdState;
15564 tsap_Config_t *pConfig;
15565 v_CONTEXT_t pVosContext = NULL;
15566 hdd_context_t *pHddCtx;
15567 int status;
15568
15569 ENTER();
15570
15571 if (NULL == pAdapter)
15572 {
15573 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15574 "%s: HDD adapter is Null", __func__);
15575 return -ENODEV;
15576 }
15577
15578 if (NULL == params)
15579 {
15580 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15581 "%s: params is Null", __func__);
15582 return -EINVAL;
15583 }
15584
15585 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15586 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015587 if (0 != status)
15588 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015589 return status;
15590 }
15591
15592 pVosContext = pHddCtx->pvosContext;
15593 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
15594
15595 if (NULL == pHostapdState)
15596 {
15597 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15598 "%s: pHostapdState is Null", __func__);
15599 return -EINVAL;
15600 }
15601
15602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
15603 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
15604
15605 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
15606 {
15607 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
15608
15609 /* default value */
15610 pConfig->num_accept_mac = 0;
15611 pConfig->num_deny_mac = 0;
15612
15613 /**
15614 * access control policy
15615 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
15616 * listed in hostapd.deny file.
15617 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
15618 * listed in hostapd.accept file.
15619 */
15620 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
15621 {
15622 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
15623 }
15624 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
15625 {
15626 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
15627 }
15628 else
15629 {
15630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15631 "%s:Acl Policy : %d is not supported",
15632 __func__, params->acl_policy);
15633 return -ENOTSUPP;
15634 }
15635
15636 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
15637 {
15638 pConfig->num_accept_mac = params->n_acl_entries;
15639 for (i = 0; i < params->n_acl_entries; i++)
15640 {
15641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15642 "** Add ACL MAC entry %i in WhiletList :"
15643 MAC_ADDRESS_STR, i,
15644 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
15645
15646 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
15647 sizeof(qcmacaddr));
15648 }
15649 }
15650 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
15651 {
15652 pConfig->num_deny_mac = params->n_acl_entries;
15653 for (i = 0; i < params->n_acl_entries; i++)
15654 {
15655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15656 "** Add ACL MAC entry %i in BlackList :"
15657 MAC_ADDRESS_STR, i,
15658 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
15659
15660 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
15661 sizeof(qcmacaddr));
15662 }
15663 }
15664
15665 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
15666 {
15667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15668 "%s: SAP Set Mac Acl fail", __func__);
15669 return -EINVAL;
15670 }
15671 }
15672 else
15673 {
15674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015675 "%s: Invalid device_mode = %s (%d)",
15676 __func__, hdd_device_modetoString(pAdapter->device_mode),
15677 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015678 return -EINVAL;
15679 }
15680
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015681 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015682 return 0;
15683}
15684
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015685static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15686 struct net_device *dev,
15687 const struct cfg80211_acl_data *params)
15688{
15689 int ret;
15690 vos_ssr_protect(__func__);
15691 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
15692 vos_ssr_unprotect(__func__);
15693
15694 return ret;
15695}
15696
Leo Chang9056f462013-08-01 19:21:11 -070015697#ifdef WLAN_NL80211_TESTMODE
15698#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070015699void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070015700(
15701 void *pAdapter,
15702 void *indCont
15703)
15704{
Leo Changd9df8aa2013-09-26 13:32:26 -070015705 tSirLPHBInd *lphbInd;
15706 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053015707 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070015708
15709 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070015710 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070015711
c_hpothu73f35e62014-04-18 13:40:08 +053015712 if (pAdapter == NULL)
15713 {
15714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15715 "%s: pAdapter is NULL\n",__func__);
15716 return;
15717 }
15718
Leo Chang9056f462013-08-01 19:21:11 -070015719 if (NULL == indCont)
15720 {
15721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070015722 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070015723 return;
15724 }
15725
c_hpothu73f35e62014-04-18 13:40:08 +053015726 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070015727 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070015728 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053015729 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070015730 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070015731 GFP_ATOMIC);
15732 if (!skb)
15733 {
15734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15735 "LPHB timeout, NL buffer alloc fail");
15736 return;
15737 }
15738
Leo Changac3ba772013-10-07 09:47:04 -070015739 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070015740 {
15741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15742 "WLAN_HDD_TM_ATTR_CMD put fail");
15743 goto nla_put_failure;
15744 }
Leo Changac3ba772013-10-07 09:47:04 -070015745 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070015746 {
15747 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15748 "WLAN_HDD_TM_ATTR_TYPE put fail");
15749 goto nla_put_failure;
15750 }
Leo Changac3ba772013-10-07 09:47:04 -070015751 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070015752 sizeof(tSirLPHBInd), lphbInd))
15753 {
15754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15755 "WLAN_HDD_TM_ATTR_DATA put fail");
15756 goto nla_put_failure;
15757 }
Leo Chang9056f462013-08-01 19:21:11 -070015758 cfg80211_testmode_event(skb, GFP_ATOMIC);
15759 return;
15760
15761nla_put_failure:
15762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15763 "NLA Put fail");
15764 kfree_skb(skb);
15765
15766 return;
15767}
15768#endif /* FEATURE_WLAN_LPHB */
15769
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015770static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070015771{
15772 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
15773 int err = 0;
15774#ifdef FEATURE_WLAN_LPHB
15775 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070015776 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015777
15778 ENTER();
15779
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015780 err = wlan_hdd_validate_context(pHddCtx);
15781 if (0 != err)
15782 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015783 return err;
15784 }
Leo Chang9056f462013-08-01 19:21:11 -070015785#endif /* FEATURE_WLAN_LPHB */
15786
15787 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
15788 if (err)
15789 {
15790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15791 "%s Testmode INV ATTR", __func__);
15792 return err;
15793 }
15794
15795 if (!tb[WLAN_HDD_TM_ATTR_CMD])
15796 {
15797 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15798 "%s Testmode INV CMD", __func__);
15799 return -EINVAL;
15800 }
15801
15802 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
15803 {
15804#ifdef FEATURE_WLAN_LPHB
15805 /* Low Power Heartbeat configuration request */
15806 case WLAN_HDD_TM_CMD_WLAN_HB:
15807 {
15808 int buf_len;
15809 void *buf;
15810 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080015811 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070015812
15813 if (!tb[WLAN_HDD_TM_ATTR_DATA])
15814 {
15815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15816 "%s Testmode INV DATA", __func__);
15817 return -EINVAL;
15818 }
15819
15820 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
15821 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080015822
15823 hb_params_temp =(tSirLPHBReq *)buf;
15824 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
15825 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
15826 return -EINVAL;
15827
Leo Chang9056f462013-08-01 19:21:11 -070015828 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
15829 if (NULL == hb_params)
15830 {
15831 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15832 "%s Request Buffer Alloc Fail", __func__);
15833 return -EINVAL;
15834 }
15835
15836 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070015837 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
15838 hb_params,
15839 wlan_hdd_cfg80211_lphb_ind_handler);
15840 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070015841 {
Leo Changd9df8aa2013-09-26 13:32:26 -070015842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15843 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070015844 vos_mem_free(hb_params);
15845 }
Leo Chang9056f462013-08-01 19:21:11 -070015846 return 0;
15847 }
15848#endif /* FEATURE_WLAN_LPHB */
15849 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015850 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15851 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070015852 return -EOPNOTSUPP;
15853 }
15854
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015855 EXIT();
15856 return err;
Leo Chang9056f462013-08-01 19:21:11 -070015857}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015858
15859static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
15860{
15861 int ret;
15862
15863 vos_ssr_protect(__func__);
15864 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
15865 vos_ssr_unprotect(__func__);
15866
15867 return ret;
15868}
Leo Chang9056f462013-08-01 19:21:11 -070015869#endif /* CONFIG_NL80211_TESTMODE */
15870
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015871static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015872 struct net_device *dev,
15873 int idx, struct survey_info *survey)
15874{
15875 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15876 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053015877 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015878 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053015879 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015880 v_S7_t snr,rssi;
15881 int status, i, j, filled = 0;
15882
15883 ENTER();
15884
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015885 if (NULL == pAdapter)
15886 {
15887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15888 "%s: HDD adapter is Null", __func__);
15889 return -ENODEV;
15890 }
15891
15892 if (NULL == wiphy)
15893 {
15894 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15895 "%s: wiphy is Null", __func__);
15896 return -ENODEV;
15897 }
15898
15899 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15900 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015901 if (0 != status)
15902 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015903 return status;
15904 }
15905
Mihir Sheted9072e02013-08-21 17:02:29 +053015906 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15907
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015908 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053015909 0 != pAdapter->survey_idx ||
15910 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015911 {
15912 /* The survey dump ops when implemented completely is expected to
15913 * return a survey of all channels and the ops is called by the
15914 * kernel with incremental values of the argument 'idx' till it
15915 * returns -ENONET. But we can only support the survey for the
15916 * operating channel for now. survey_idx is used to track
15917 * that the ops is called only once and then return -ENONET for
15918 * the next iteration
15919 */
15920 pAdapter->survey_idx = 0;
15921 return -ENONET;
15922 }
15923
15924 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15925
15926 wlan_hdd_get_snr(pAdapter, &snr);
15927 wlan_hdd_get_rssi(pAdapter, &rssi);
15928
15929 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
15930 hdd_wlan_get_freq(channel, &freq);
15931
15932
15933 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
15934 {
15935 if (NULL == wiphy->bands[i])
15936 {
15937 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
15938 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
15939 continue;
15940 }
15941
15942 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
15943 {
15944 struct ieee80211_supported_band *band = wiphy->bands[i];
15945
15946 if (band->channels[j].center_freq == (v_U16_t)freq)
15947 {
15948 survey->channel = &band->channels[j];
15949 /* The Rx BDs contain SNR values in dB for the received frames
15950 * while the supplicant expects noise. So we calculate and
15951 * return the value of noise (dBm)
15952 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
15953 */
15954 survey->noise = rssi - snr;
15955 survey->filled = SURVEY_INFO_NOISE_DBM;
15956 filled = 1;
15957 }
15958 }
15959 }
15960
15961 if (filled)
15962 pAdapter->survey_idx = 1;
15963 else
15964 {
15965 pAdapter->survey_idx = 0;
15966 return -ENONET;
15967 }
15968
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015969 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015970 return 0;
15971}
15972
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015973static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
15974 struct net_device *dev,
15975 int idx, struct survey_info *survey)
15976{
15977 int ret;
15978
15979 vos_ssr_protect(__func__);
15980 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
15981 vos_ssr_unprotect(__func__);
15982
15983 return ret;
15984}
15985
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015986/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015987 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015988 * this is called when cfg80211 driver resume
15989 * driver updates latest sched_scan scan result(if any) to cfg80211 database
15990 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015991int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015992{
15993 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15994 hdd_adapter_t *pAdapter;
15995 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15996 VOS_STATUS status = VOS_STATUS_SUCCESS;
15997
15998 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015999
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016000 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016001 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016002 return 0;
16003 }
16004
16005 spin_lock(&pHddCtx->schedScan_lock);
16006 pHddCtx->isWiphySuspended = FALSE;
16007 if (TRUE != pHddCtx->isSchedScanUpdatePending)
16008 {
16009 spin_unlock(&pHddCtx->schedScan_lock);
16010 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16011 "%s: Return resume is not due to PNO indication", __func__);
16012 return 0;
16013 }
16014 // Reset flag to avoid updatating cfg80211 data old results again
16015 pHddCtx->isSchedScanUpdatePending = FALSE;
16016 spin_unlock(&pHddCtx->schedScan_lock);
16017
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016018
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016019 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
16020
16021 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
16022 {
16023 pAdapter = pAdapterNode->pAdapter;
16024 if ( (NULL != pAdapter) &&
16025 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
16026 {
16027 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016028 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16030 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016031 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016032 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016033 {
16034 /* Acquire wakelock to handle the case where APP's tries to
16035 * suspend immediately after updating the scan results. Whis
16036 * results in app's is in suspended state and not able to
16037 * process the connect request to AP
16038 */
16039 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016040 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016041 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016042
16043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16044 "%s : cfg80211 scan result database updated", __func__);
16045
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016046 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016047 return 0;
16048
16049 }
16050 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16051 pAdapterNode = pNext;
16052 }
16053
16054 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16055 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016056 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016057 return 0;
16058}
16059
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016060int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
16061{
16062 int ret;
16063
16064 vos_ssr_protect(__func__);
16065 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
16066 vos_ssr_unprotect(__func__);
16067
16068 return ret;
16069}
16070
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016071/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016072 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016073 * this is called when cfg80211 driver suspends
16074 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016075int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016076 struct cfg80211_wowlan *wow)
16077{
16078 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016079 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016080
16081 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016082
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016083 ret = wlan_hdd_validate_context(pHddCtx);
16084 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016085 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016086 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016087 }
16088
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016089
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016090 pHddCtx->isWiphySuspended = TRUE;
16091
16092 EXIT();
16093
16094 return 0;
16095}
16096
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016097int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
16098 struct cfg80211_wowlan *wow)
16099{
16100 int ret;
16101
16102 vos_ssr_protect(__func__);
16103 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
16104 vos_ssr_unprotect(__func__);
16105
16106 return ret;
16107}
Jeff Johnson295189b2012-06-20 16:38:30 -070016108/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016109static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070016110{
16111 .add_virtual_intf = wlan_hdd_add_virtual_intf,
16112 .del_virtual_intf = wlan_hdd_del_virtual_intf,
16113 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
16114 .change_station = wlan_hdd_change_station,
16115#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
16116 .add_beacon = wlan_hdd_cfg80211_add_beacon,
16117 .del_beacon = wlan_hdd_cfg80211_del_beacon,
16118 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016119#else
16120 .start_ap = wlan_hdd_cfg80211_start_ap,
16121 .change_beacon = wlan_hdd_cfg80211_change_beacon,
16122 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070016123#endif
16124 .change_bss = wlan_hdd_cfg80211_change_bss,
16125 .add_key = wlan_hdd_cfg80211_add_key,
16126 .get_key = wlan_hdd_cfg80211_get_key,
16127 .del_key = wlan_hdd_cfg80211_del_key,
16128 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016129#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070016130 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016131#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016132 .scan = wlan_hdd_cfg80211_scan,
16133 .connect = wlan_hdd_cfg80211_connect,
16134 .disconnect = wlan_hdd_cfg80211_disconnect,
16135 .join_ibss = wlan_hdd_cfg80211_join_ibss,
16136 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
16137 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
16138 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
16139 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070016140 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
16141 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053016142 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070016143#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16144 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
16145 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
16146 .set_txq_params = wlan_hdd_set_txq_params,
16147#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016148 .get_station = wlan_hdd_cfg80211_get_station,
16149 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
16150 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016151 .add_station = wlan_hdd_cfg80211_add_station,
16152#ifdef FEATURE_WLAN_LFR
16153 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
16154 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
16155 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
16156#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016157#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
16158 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
16159#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016160#ifdef FEATURE_WLAN_TDLS
16161 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
16162 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
16163#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016164#ifdef WLAN_FEATURE_GTK_OFFLOAD
16165 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
16166#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016167#ifdef FEATURE_WLAN_SCAN_PNO
16168 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
16169 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
16170#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016171 .resume = wlan_hdd_cfg80211_resume_wlan,
16172 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016173 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070016174#ifdef WLAN_NL80211_TESTMODE
16175 .testmode_cmd = wlan_hdd_cfg80211_testmode,
16176#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016177 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070016178};
16179