blob: da39e186473182902b59e89820308f7c42212aa1 [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
4838#ifdef WLAN_FEATURE_EXTSCAN
4839 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
4840 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
4841 hddLog(LOG1, FL("EXTScan is supported by firmware"));
4842 fset |= WIFI_FEATURE_EXTSCAN;
4843 }
4844#endif
4845
4846#ifdef WLAN_FEATURE_NAN
4847 if (sme_IsFeatureSupportedByFW(NAN)) {
4848 hddLog(LOG1, FL("NAN is supported by firmware"));
4849 fset |= WIFI_FEATURE_NAN;
4850 }
4851#endif
4852
4853 /* D2D RTT is not supported currently by default */
4854 if (sme_IsFeatureSupportedByFW(RTT)) {
4855 hddLog(LOG1, FL("RTT is supported by firmware"));
4856 fset |= WIFI_FEATURE_D2AP_RTT;
4857 }
4858
4859#ifdef FEATURE_WLAN_BATCH_SCAN
4860 if (fset & WIFI_FEATURE_EXTSCAN) {
4861 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
4862 fset &= ~WIFI_FEATURE_BATCH_SCAN;
4863 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
4864 hddLog(LOG1, FL("Batch scan is supported by firmware"));
4865 fset |= WIFI_FEATURE_BATCH_SCAN;
4866 }
4867#endif
4868
4869#ifdef FEATURE_WLAN_SCAN_PNO
4870 if (pHddCtx->cfg_ini->configPNOScanSupport &&
4871 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
4872 hddLog(LOG1, FL("PNO is supported by firmware"));
4873 fset |= WIFI_FEATURE_PNO;
4874 }
4875#endif
4876
4877 /* STA+STA is supported currently by default */
4878 fset |= WIFI_FEATURE_ADDITIONAL_STA;
4879
4880#ifdef FEATURE_WLAN_TDLS
4881 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
4882 sme_IsFeatureSupportedByFW(TDLS)) {
4883 hddLog(LOG1, FL("TDLS is supported by firmware"));
4884 fset |= WIFI_FEATURE_TDLS;
4885 }
4886
4887 /* TDLS_OFFCHANNEL is not supported currently by default */
4888#endif
4889
4890#ifdef WLAN_AP_STA_CONCURRENCY
4891 /* AP+STA concurrency is supported currently by default */
4892 fset |= WIFI_FEATURE_AP_STA;
4893#endif
4894
4895 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
4896 NLMSG_HDRLEN);
4897
4898 if (!skb) {
4899 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4900 return -EINVAL;
4901 }
4902 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
4903
4904 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
4905 hddLog(LOGE, FL("nla put fail"));
4906 goto nla_put_failure;
4907 }
4908
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304909 ret = cfg80211_vendor_cmd_reply(skb);
4910 EXIT();
4911 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05304912
4913nla_put_failure:
4914 kfree_skb(skb);
4915 return -EINVAL;
4916}
4917
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304918static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304919wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
4920 struct wireless_dev *wdev,
4921 const void *data, int data_len)
4922{
4923 int ret = 0;
4924
4925 vos_ssr_protect(__func__);
4926 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
4927 vos_ssr_unprotect(__func__);
4928
4929 return ret;
4930}
4931
4932static int
4933__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304934 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304935 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304936{
4937 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
4938 uint8_t i, feature_sets, max_feature_sets;
4939 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
4940 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304941 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4942 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304943
4944 ENTER();
4945
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304946 ret = wlan_hdd_validate_context(pHddCtx);
4947 if (0 != ret)
4948 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304949 return ret;
4950 }
4951
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304952 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
4953 data, data_len, NULL)) {
4954 hddLog(LOGE, FL("Invalid ATTR"));
4955 return -EINVAL;
4956 }
4957
4958 /* Parse and fetch max feature set */
4959 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
4960 hddLog(LOGE, FL("Attr max feature set size failed"));
4961 return -EINVAL;
4962 }
4963 max_feature_sets = nla_get_u32(
4964 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
4965 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
4966
4967 /* Fill feature combination matrix */
4968 feature_sets = 0;
4969 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4970 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4971 WIFI_FEATURE_P2P;
4972
4973 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4974 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4975 WIFI_FEATURE_SOFT_AP;
4976
4977 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4978 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
4979 WIFI_FEATURE_SOFT_AP;
4980
4981 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4982 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4983 WIFI_FEATURE_SOFT_AP |
4984 WIFI_FEATURE_P2P;
4985
4986 /* Add more feature combinations here */
4987
4988 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
4989 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
4990 hddLog(LOG1, "Feature set matrix");
4991 for (i = 0; i < feature_sets; i++)
4992 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
4993
4994 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4995 sizeof(u32) * feature_sets +
4996 NLMSG_HDRLEN);
4997
4998 if (reply_skb) {
4999 if (nla_put_u32(reply_skb,
5000 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5001 feature_sets) ||
5002 nla_put(reply_skb,
5003 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5004 sizeof(u32) * feature_sets, feature_set_matrix)) {
5005 hddLog(LOGE, FL("nla put fail"));
5006 kfree_skb(reply_skb);
5007 return -EINVAL;
5008 }
5009
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305010 ret = cfg80211_vendor_cmd_reply(reply_skb);
5011 EXIT();
5012 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305013 }
5014 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5015 return -ENOMEM;
5016
5017max_buffer_err:
5018 hddLog(LOGE, FL("Feature set max buffer size reached. feature_sets(%d) max(%d)"),
5019 feature_sets, WLAN_HDD_MAX_FEATURE_SET);
5020 return -EINVAL;
5021}
5022
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305023static int
5024wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5025 struct wireless_dev *wdev,
5026 const void *data, int data_len)
5027{
5028 int ret = 0;
5029
5030 vos_ssr_protect(__func__);
5031 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5032 data_len);
5033 vos_ssr_unprotect(__func__);
5034
5035 return ret;
5036}
5037
Agarwal Ashish738843c2014-09-25 12:27:56 +05305038static const struct nla_policy
5039wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5040 +1] =
5041{
5042 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5043};
5044
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305045static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305046 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305047 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305048 int data_len)
5049{
5050 struct net_device *dev = wdev->netdev;
5051 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5052 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5053 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5054 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5055 eHalStatus status;
5056 u32 dfsFlag = 0;
5057
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305058 ENTER();
5059
Agarwal Ashish738843c2014-09-25 12:27:56 +05305060 status = wlan_hdd_validate_context(pHddCtx);
5061 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305062 return -EINVAL;
5063 }
5064 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5065 data, data_len,
5066 wlan_hdd_set_no_dfs_flag_config_policy)) {
5067 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5068 return -EINVAL;
5069 }
5070
5071 /* Parse and fetch required bandwidth kbps */
5072 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5073 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5074 return -EINVAL;
5075 }
5076
5077 dfsFlag = nla_get_u32(
5078 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5079 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5080 dfsFlag);
5081
5082 pHddCtx->disable_dfs_flag = dfsFlag;
5083
5084 sme_disable_dfs_channel(hHal, dfsFlag);
5085 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305086
5087 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305088 return 0;
5089}
Atul Mittal115287b2014-07-08 13:26:33 +05305090
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305091static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5092 struct wireless_dev *wdev,
5093 const void *data,
5094 int data_len)
5095{
5096 int ret = 0;
5097
5098 vos_ssr_protect(__func__);
5099 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5100 vos_ssr_unprotect(__func__);
5101
5102 return ret;
5103
5104}
5105
Mukul Sharma2a271632014-10-13 14:59:01 +05305106const struct
5107nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5108{
5109 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5110 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5111};
5112
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305113static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305114 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305115{
5116
5117 u8 bssid[6] = {0};
5118 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5119 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5120 eHalStatus status = eHAL_STATUS_SUCCESS;
5121 v_U32_t isFwrRoamEnabled = FALSE;
5122 int ret;
5123
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305124 ENTER();
5125
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305126 ret = wlan_hdd_validate_context(pHddCtx);
5127 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305128 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305129 }
5130
5131 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5132 data, data_len,
5133 qca_wlan_vendor_attr);
5134 if (ret){
5135 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5136 return -EINVAL;
5137 }
5138
5139 /* Parse and fetch Enable flag */
5140 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5141 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5142 return -EINVAL;
5143 }
5144
5145 isFwrRoamEnabled = nla_get_u32(
5146 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5147
5148 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5149
5150 /* Parse and fetch bssid */
5151 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5152 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5153 return -EINVAL;
5154 }
5155
5156 memcpy(bssid, nla_data(
5157 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5158 sizeof(bssid));
5159 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5160
5161 //Update roaming
5162 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305163 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305164 return status;
5165}
5166
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305167static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5168 struct wireless_dev *wdev, const void *data, int data_len)
5169{
5170 int ret = 0;
5171
5172 vos_ssr_protect(__func__);
5173 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5174 vos_ssr_unprotect(__func__);
5175
5176 return ret;
5177}
5178
Sunil Duttc69bccb2014-05-26 21:30:20 +05305179const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
5180{
Mukul Sharma2a271632014-10-13 14:59:01 +05305181 {
5182 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5183 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
5184 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5185 WIPHY_VENDOR_CMD_NEED_NETDEV |
5186 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305187 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05305188 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305189#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5190 {
5191 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5192 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
5193 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5194 WIPHY_VENDOR_CMD_NEED_NETDEV |
5195 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305196 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05305197 },
5198
5199 {
5200 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5201 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
5202 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5203 WIPHY_VENDOR_CMD_NEED_NETDEV |
5204 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305205 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05305206 },
5207
5208 {
5209 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5210 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
5211 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5212 WIPHY_VENDOR_CMD_NEED_NETDEV |
5213 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305214 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05305215 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305216#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305217#ifdef WLAN_FEATURE_EXTSCAN
5218 {
5219 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5220 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
5221 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5222 WIPHY_VENDOR_CMD_NEED_NETDEV |
5223 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305224 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05305225 },
5226 {
5227 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5228 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
5229 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5230 WIPHY_VENDOR_CMD_NEED_NETDEV |
5231 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305232 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05305233 },
5234 {
5235 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5236 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
5237 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5238 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305239 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05305240 },
5241 {
5242 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5243 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
5244 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5245 WIPHY_VENDOR_CMD_NEED_NETDEV |
5246 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305247 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05305248 },
5249 {
5250 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5251 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
5252 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5253 WIPHY_VENDOR_CMD_NEED_NETDEV |
5254 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305255 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05305256 },
5257 {
5258 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5259 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
5260 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5261 WIPHY_VENDOR_CMD_NEED_NETDEV |
5262 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305263 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305264 },
5265 {
5266 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5267 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
5268 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5269 WIPHY_VENDOR_CMD_NEED_NETDEV |
5270 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305271 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305272 },
5273 {
5274 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5275 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
5276 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5277 WIPHY_VENDOR_CMD_NEED_NETDEV |
5278 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305279 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305280 },
5281 {
5282 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5283 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
5284 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5285 WIPHY_VENDOR_CMD_NEED_NETDEV |
5286 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305287 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305288 },
5289#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305290/*EXT TDLS*/
5291 {
5292 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5293 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
5294 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5295 WIPHY_VENDOR_CMD_NEED_NETDEV |
5296 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305297 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05305298 },
5299 {
5300 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5301 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
5302 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5303 WIPHY_VENDOR_CMD_NEED_NETDEV |
5304 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305305 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05305306 },
5307 {
5308 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5309 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
5310 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5311 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305312 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05305313 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05305314 {
5315 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5316 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
5317 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5318 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305319 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05305320 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05305321 {
5322 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5323 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
5324 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5325 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305326 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05305327 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305328 {
5329 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5330 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
5331 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5332 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305333 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305334 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305335 {
5336 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5337 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
5338 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5339 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305340 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305341 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305342};
5343
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005344/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05305345static const
5346struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005347{
5348#ifdef FEATURE_WLAN_CH_AVOID
5349 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05305350 .vendor_id = QCA_NL80211_VENDOR_ID,
5351 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005352 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305353#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
5354#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5355 {
5356 /* Index = 1*/
5357 .vendor_id = QCA_NL80211_VENDOR_ID,
5358 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
5359 },
5360 {
5361 /* Index = 2*/
5362 .vendor_id = QCA_NL80211_VENDOR_ID,
5363 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
5364 },
5365 {
5366 /* Index = 3*/
5367 .vendor_id = QCA_NL80211_VENDOR_ID,
5368 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
5369 },
5370 {
5371 /* Index = 4*/
5372 .vendor_id = QCA_NL80211_VENDOR_ID,
5373 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
5374 },
5375 {
5376 /* Index = 5*/
5377 .vendor_id = QCA_NL80211_VENDOR_ID,
5378 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
5379 },
5380 {
5381 /* Index = 6*/
5382 .vendor_id = QCA_NL80211_VENDOR_ID,
5383 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
5384 },
5385#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305386#ifdef WLAN_FEATURE_EXTSCAN
5387 {
5388 .vendor_id = QCA_NL80211_VENDOR_ID,
5389 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
5390 },
5391 {
5392 .vendor_id = QCA_NL80211_VENDOR_ID,
5393 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
5394 },
5395 {
5396 .vendor_id = QCA_NL80211_VENDOR_ID,
5397 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
5398 },
5399 {
5400 .vendor_id = QCA_NL80211_VENDOR_ID,
5401 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
5402 },
5403 {
5404 .vendor_id = QCA_NL80211_VENDOR_ID,
5405 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
5406 },
5407 {
5408 .vendor_id = QCA_NL80211_VENDOR_ID,
5409 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
5410 },
5411 {
5412 .vendor_id = QCA_NL80211_VENDOR_ID,
5413 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
5414 },
5415 {
5416 .vendor_id = QCA_NL80211_VENDOR_ID,
5417 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
5418 },
5419 {
5420 .vendor_id = QCA_NL80211_VENDOR_ID,
5421 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
5422 },
5423 {
5424 .vendor_id = QCA_NL80211_VENDOR_ID,
5425 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
5426 },
5427 {
5428 .vendor_id = QCA_NL80211_VENDOR_ID,
5429 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
5430 },
5431 {
5432 .vendor_id = QCA_NL80211_VENDOR_ID,
5433 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
5434 },
5435 {
5436 .vendor_id = QCA_NL80211_VENDOR_ID,
5437 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
5438 },
5439#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305440/*EXT TDLS*/
5441 {
5442 .vendor_id = QCA_NL80211_VENDOR_ID,
5443 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
5444 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005445};
5446
Jeff Johnson295189b2012-06-20 16:38:30 -07005447/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305448 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305449 * This function is called by hdd_wlan_startup()
5450 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305451 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07005452 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305453struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07005454{
5455 struct wiphy *wiphy;
5456 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305457 /*
5458 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07005459 */
5460 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
5461
5462 if (!wiphy)
5463 {
5464 /* Print error and jump into err label and free the memory */
5465 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
5466 return NULL;
5467 }
5468
Sunil Duttc69bccb2014-05-26 21:30:20 +05305469
Jeff Johnson295189b2012-06-20 16:38:30 -07005470 return wiphy;
5471}
5472
5473/*
5474 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305475 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07005476 * private ioctl to change the band value
5477 */
5478int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
5479{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305480 int i, j;
5481 eNVChannelEnabledType channelEnabledState;
5482
Jeff Johnsone7245742012-09-05 17:12:55 -07005483 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305484
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305485 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005486 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305487
5488 if (NULL == wiphy->bands[i])
5489 {
5490 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5491 __func__, i);
5492 continue;
5493 }
5494
5495 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5496 {
5497 struct ieee80211_supported_band *band = wiphy->bands[i];
5498
5499 channelEnabledState = vos_nv_getChannelEnabledState(
5500 band->channels[j].hw_value);
5501
5502 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
5503 {
Abhishek Singh678227a2014-11-04 10:52:38 +05305504 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305505 continue;
5506 }
5507 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
5508 {
5509 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5510 continue;
5511 }
5512
5513 if (NV_CHANNEL_DISABLE == channelEnabledState ||
5514 NV_CHANNEL_INVALID == channelEnabledState)
5515 {
5516 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5517 }
5518 else if (NV_CHANNEL_DFS == channelEnabledState)
5519 {
5520 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5521 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
5522 }
5523 else
5524 {
5525 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
5526 |IEEE80211_CHAN_RADAR);
5527 }
5528 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005529 }
5530 return 0;
5531}
5532/*
5533 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305534 * This function is called by hdd_wlan_startup()
5535 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005536 * This function is used to initialize and register wiphy structure.
5537 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305538int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005539 struct wiphy *wiphy,
5540 hdd_config_t *pCfg
5541 )
5542{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305543 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305544 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5545
Jeff Johnsone7245742012-09-05 17:12:55 -07005546 ENTER();
5547
Jeff Johnson295189b2012-06-20 16:38:30 -07005548 /* Now bind the underlying wlan device with wiphy */
5549 set_wiphy_dev(wiphy, dev);
5550
5551 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005552
Kiet Lam6c583332013-10-14 05:37:09 +05305553#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005554 /* the flag for the other case would be initialzed in
5555 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005556 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305557#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005558
Amar Singhalfddc28c2013-09-05 13:03:40 -07005559 /* This will disable updating of NL channels from passive to
5560 * active if a beacon is received on passive channel. */
5561 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07005562
Amar Singhalfddc28c2013-09-05 13:03:40 -07005563
Amar Singhala49cbc52013-10-08 18:37:44 -07005564
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005565#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005566 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5567 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5568 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005569 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05305570 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005571#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005572
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005573#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005574 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005575#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005576 || pCfg->isFastRoamIniFeatureEnabled
5577#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005578#ifdef FEATURE_WLAN_ESE
5579 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005580#endif
5581 )
5582 {
5583 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5584 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005585#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005586#ifdef FEATURE_WLAN_TDLS
5587 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5588 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5589#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305590#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305591 if (pCfg->configPNOScanSupport)
5592 {
5593 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5594 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5595 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5596 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5597 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305598#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005599
Amar Singhalfddc28c2013-09-05 13:03:40 -07005600#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005601 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5602 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005603 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005604 driver need to determine what to do with both
5605 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005606
5607 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005608#else
5609 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005610#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005611
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305612 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5613
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05305614 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005615
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305616 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5617
Jeff Johnson295189b2012-06-20 16:38:30 -07005618 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305619 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07005620 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07005621 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5622 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005623 | BIT(NL80211_IFTYPE_AP);
5624
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305625 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005626 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305627#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5628 if( pCfg->enableMCC )
5629 {
5630 /* Currently, supports up to two channels */
5631 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005632
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305633 if( !pCfg->allowMCCGODiffBI )
5634 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005635
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305636 }
5637 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5638 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005639#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305640 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005641
Jeff Johnson295189b2012-06-20 16:38:30 -07005642 /* Before registering we need to update the ht capabilitied based
5643 * on ini values*/
5644 if( !pCfg->ShortGI20MhzEnable )
5645 {
5646 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5647 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5648 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5649 }
5650
5651 if( !pCfg->ShortGI40MhzEnable )
5652 {
5653 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5654 }
5655
5656 if( !pCfg->nChannelBondingMode5GHz )
5657 {
5658 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5659 }
5660
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305661 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305662 if (true == hdd_is_5g_supported(pHddCtx))
5663 {
5664 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5665 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305666
5667 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5668 {
5669
5670 if (NULL == wiphy->bands[i])
5671 {
5672 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5673 __func__, i);
5674 continue;
5675 }
5676
5677 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5678 {
5679 struct ieee80211_supported_band *band = wiphy->bands[i];
5680
5681 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5682 {
5683 // Enable social channels for P2P
5684 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5685 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5686 else
5687 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5688 continue;
5689 }
5690 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5691 {
5692 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5693 continue;
5694 }
5695 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005696 }
5697 /*Initialise the supported cipher suite details*/
5698 wiphy->cipher_suites = hdd_cipher_suites;
5699 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5700
5701 /*signal strength in mBm (100*dBm) */
5702 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5703
5704#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305705 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005706#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005707
Sunil Duttc69bccb2014-05-26 21:30:20 +05305708 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
5709 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005710 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
5711 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
5712
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305713 EXIT();
5714 return 0;
5715}
5716
5717/* In this function we are registering wiphy. */
5718int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
5719{
5720 ENTER();
5721 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005722 if (0 > wiphy_register(wiphy))
5723 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305724 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07005725 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
5726 return -EIO;
5727 }
5728
5729 EXIT();
5730 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305731}
Jeff Johnson295189b2012-06-20 16:38:30 -07005732
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305733/* In this function we are updating channel list when,
5734 regulatory domain is FCC and country code is US.
5735 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
5736 As per FCC smart phone is not a indoor device.
5737 GO should not opeate on indoor channels */
5738void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
5739{
5740 int j;
5741 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5742 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
5743 //Default counrtycode from NV at the time of wiphy initialization.
5744 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
5745 &defaultCountryCode[0]))
5746 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005747 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305748 }
5749 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
5750 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305751 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
5752 {
5753 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
5754 return;
5755 }
5756 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
5757 {
5758 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
5759 // Mark UNII -1 band channel as passive
5760 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
5761 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
5762 }
5763 }
5764}
5765
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305766/* This function registers for all frame which supplicant is interested in */
5767void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005768{
Jeff Johnson295189b2012-06-20 16:38:30 -07005769 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5770 /* Register for all P2P action, public action etc frames */
5771 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5772
Jeff Johnsone7245742012-09-05 17:12:55 -07005773 ENTER();
5774
Jeff Johnson295189b2012-06-20 16:38:30 -07005775 /* Right now we are registering these frame when driver is getting
5776 initialized. Once we will move to 2.6.37 kernel, in which we have
5777 frame register ops, we will move this code as a part of that */
5778 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305779 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07005780 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5781
5782 /* GAS Initial Response */
5783 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5784 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305785
Jeff Johnson295189b2012-06-20 16:38:30 -07005786 /* GAS Comeback Request */
5787 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5788 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5789
5790 /* GAS Comeback Response */
5791 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5792 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5793
5794 /* P2P Public Action */
5795 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305796 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005797 P2P_PUBLIC_ACTION_FRAME_SIZE );
5798
5799 /* P2P Action */
5800 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5801 (v_U8_t*)P2P_ACTION_FRAME,
5802 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07005803
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05305804 /* WNM BSS Transition Request frame */
5805 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5806 (v_U8_t*)WNM_BSS_ACTION_FRAME,
5807 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005808
5809 /* WNM-Notification */
5810 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5811 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5812 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005813}
5814
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305815void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005816{
Jeff Johnson295189b2012-06-20 16:38:30 -07005817 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5818 /* Register for all P2P action, public action etc frames */
5819 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5820
Jeff Johnsone7245742012-09-05 17:12:55 -07005821 ENTER();
5822
Jeff Johnson295189b2012-06-20 16:38:30 -07005823 /* Right now we are registering these frame when driver is getting
5824 initialized. Once we will move to 2.6.37 kernel, in which we have
5825 frame register ops, we will move this code as a part of that */
5826 /* GAS Initial Request */
5827
5828 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5829 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5830
5831 /* GAS Initial Response */
5832 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5833 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305834
Jeff Johnson295189b2012-06-20 16:38:30 -07005835 /* GAS Comeback Request */
5836 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5837 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5838
5839 /* GAS Comeback Response */
5840 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5841 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5842
5843 /* P2P Public Action */
5844 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305845 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005846 P2P_PUBLIC_ACTION_FRAME_SIZE );
5847
5848 /* P2P Action */
5849 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5850 (v_U8_t*)P2P_ACTION_FRAME,
5851 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005852 /* WNM-Notification */
5853 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5854 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5855 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005856}
5857
5858#ifdef FEATURE_WLAN_WAPI
5859void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
5860 const u8 *mac_addr, u8 *key , int key_Len)
5861{
5862 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5863 tCsrRoamSetKey setKey;
5864 v_BOOL_t isConnected = TRUE;
5865 int status = 0;
5866 v_U32_t roamId= 0xFF;
5867 tANI_U8 *pKeyPtr = NULL;
5868 int n = 0;
5869
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305870 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
5871 __func__, hdd_device_modetoString(pAdapter->device_mode),
5872 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005873
Gopichand Nakkalae7480202013-02-11 15:24:22 +05305874 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005875 setKey.keyId = key_index; // Store Key ID
5876 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
5877 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
5878 setKey.paeRole = 0 ; // the PAE role
5879 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
5880 {
5881 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
5882 }
5883 else
5884 {
5885 isConnected = hdd_connIsConnected(pHddStaCtx);
5886 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
5887 }
5888 setKey.keyLength = key_Len;
5889 pKeyPtr = setKey.Key;
5890 memcpy( pKeyPtr, key, key_Len);
5891
Arif Hussain6d2a3322013-11-17 19:50:10 -08005892 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005893 __func__, key_Len);
5894 for (n = 0 ; n < key_Len; n++)
5895 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
5896 __func__,n,setKey.Key[n]);
5897
5898 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
5899 if ( isConnected )
5900 {
5901 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
5902 pAdapter->sessionId, &setKey, &roamId );
5903 }
5904 if ( status != 0 )
5905 {
5906 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5907 "[%4d] sme_RoamSetKey returned ERROR status= %d",
5908 __LINE__, status );
5909 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
5910 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05305911 /* Need to clear any trace of key value in the memory.
5912 * Thus zero out the memory even though it is local
5913 * variable.
5914 */
5915 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005916}
5917#endif /* FEATURE_WLAN_WAPI*/
5918
5919#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305920int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005921 beacon_data_t **ppBeacon,
5922 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005923#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305924int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005925 beacon_data_t **ppBeacon,
5926 struct cfg80211_beacon_data *params,
5927 int dtim_period)
5928#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305929{
Jeff Johnson295189b2012-06-20 16:38:30 -07005930 int size;
5931 beacon_data_t *beacon = NULL;
5932 beacon_data_t *old = NULL;
5933 int head_len,tail_len;
5934
Jeff Johnsone7245742012-09-05 17:12:55 -07005935 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005936 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305937 {
5938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5939 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005940 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305941 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005942
5943 old = pAdapter->sessionCtx.ap.beacon;
5944
5945 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305946 {
5947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5948 FL("session(%d) old and new heads points to NULL"),
5949 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005950 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305951 }
5952
5953 if (params->tail && !params->tail_len)
5954 {
5955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5956 FL("tail_len is zero but tail is not NULL"));
5957 return -EINVAL;
5958 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005959
Jeff Johnson295189b2012-06-20 16:38:30 -07005960#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
5961 /* Kernel 3.0 is not updating dtim_period for set beacon */
5962 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305963 {
5964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5965 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005966 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305967 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005968#endif
5969
5970 if(params->head)
5971 head_len = params->head_len;
5972 else
5973 head_len = old->head_len;
5974
5975 if(params->tail || !old)
5976 tail_len = params->tail_len;
5977 else
5978 tail_len = old->tail_len;
5979
5980 size = sizeof(beacon_data_t) + head_len + tail_len;
5981
5982 beacon = kzalloc(size, GFP_KERNEL);
5983
5984 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305985 {
5986 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5987 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005988 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305989 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005990
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005991#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005992 if(params->dtim_period || !old )
5993 beacon->dtim_period = params->dtim_period;
5994 else
5995 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005996#else
5997 if(dtim_period || !old )
5998 beacon->dtim_period = dtim_period;
5999 else
6000 beacon->dtim_period = old->dtim_period;
6001#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306002
Jeff Johnson295189b2012-06-20 16:38:30 -07006003 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6004 beacon->tail = beacon->head + head_len;
6005 beacon->head_len = head_len;
6006 beacon->tail_len = tail_len;
6007
6008 if(params->head) {
6009 memcpy (beacon->head,params->head,beacon->head_len);
6010 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306011 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006012 if(old)
6013 memcpy (beacon->head,old->head,beacon->head_len);
6014 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306015
Jeff Johnson295189b2012-06-20 16:38:30 -07006016 if(params->tail) {
6017 memcpy (beacon->tail,params->tail,beacon->tail_len);
6018 }
6019 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306020 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006021 memcpy (beacon->tail,old->tail,beacon->tail_len);
6022 }
6023
6024 *ppBeacon = beacon;
6025
6026 kfree(old);
6027
6028 return 0;
6029
6030}
Jeff Johnson295189b2012-06-20 16:38:30 -07006031
6032v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
6033{
6034 int left = length;
6035 v_U8_t *ptr = pIes;
6036 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306037
Jeff Johnson295189b2012-06-20 16:38:30 -07006038 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306039 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006040 elem_id = ptr[0];
6041 elem_len = ptr[1];
6042 left -= 2;
6043 if(elem_len > left)
6044 {
6045 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006046 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006047 eid,elem_len,left);
6048 return NULL;
6049 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306050 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006051 {
6052 return ptr;
6053 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306054
Jeff Johnson295189b2012-06-20 16:38:30 -07006055 left -= elem_len;
6056 ptr += (elem_len + 2);
6057 }
6058 return NULL;
6059}
6060
Jeff Johnson295189b2012-06-20 16:38:30 -07006061/* Check if rate is 11g rate or not */
6062static int wlan_hdd_rate_is_11g(u8 rate)
6063{
Sanjay Devnani28322e22013-06-21 16:13:40 -07006064 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006065 u8 i;
6066 for (i = 0; i < 8; i++)
6067 {
6068 if(rate == gRateArray[i])
6069 return TRUE;
6070 }
6071 return FALSE;
6072}
6073
6074/* Check for 11g rate and set proper 11g only mode */
6075static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
6076 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
6077{
6078 u8 i, num_rates = pIe[0];
6079
6080 pIe += 1;
6081 for ( i = 0; i < num_rates; i++)
6082 {
6083 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
6084 {
6085 /* If rate set have 11g rate than change the mode to 11G */
6086 *pSapHw_mode = eSAP_DOT11_MODE_11g;
6087 if (pIe[i] & BASIC_RATE_MASK)
6088 {
6089 /* If we have 11g rate as basic rate, it means mode
6090 is 11g only mode.
6091 */
6092 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
6093 *pCheckRatesfor11g = FALSE;
6094 }
6095 }
6096 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6097 {
6098 *require_ht = TRUE;
6099 }
6100 }
6101 return;
6102}
6103
6104static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
6105{
6106 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6107 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6108 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6109 u8 checkRatesfor11g = TRUE;
6110 u8 require_ht = FALSE;
6111 u8 *pIe=NULL;
6112
6113 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
6114
6115 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6116 pBeacon->head_len, WLAN_EID_SUPP_RATES);
6117 if (pIe != NULL)
6118 {
6119 pIe += 1;
6120 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6121 &pConfig->SapHw_mode);
6122 }
6123
6124 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6125 WLAN_EID_EXT_SUPP_RATES);
6126 if (pIe != NULL)
6127 {
6128
6129 pIe += 1;
6130 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6131 &pConfig->SapHw_mode);
6132 }
6133
6134 if( pConfig->channel > 14 )
6135 {
6136 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
6137 }
6138
6139 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6140 WLAN_EID_HT_CAPABILITY);
6141
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306142 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006143 {
6144 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
6145 if(require_ht)
6146 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
6147 }
6148}
6149
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306150static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
6151 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
6152{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006153 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306154 v_U8_t *pIe = NULL;
6155 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6156
6157 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6158 pBeacon->tail, pBeacon->tail_len);
6159
6160 if (pIe)
6161 {
6162 ielen = pIe[1] + 2;
6163 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6164 {
6165 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
6166 }
6167 else
6168 {
6169 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
6170 return -EINVAL;
6171 }
6172 *total_ielen += ielen;
6173 }
6174 return 0;
6175}
6176
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006177static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
6178 v_U8_t *genie, v_U8_t *total_ielen)
6179{
6180 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6181 int left = pBeacon->tail_len;
6182 v_U8_t *ptr = pBeacon->tail;
6183 v_U8_t elem_id, elem_len;
6184 v_U16_t ielen = 0;
6185
6186 if ( NULL == ptr || 0 == left )
6187 return;
6188
6189 while (left >= 2)
6190 {
6191 elem_id = ptr[0];
6192 elem_len = ptr[1];
6193 left -= 2;
6194 if (elem_len > left)
6195 {
6196 hddLog( VOS_TRACE_LEVEL_ERROR,
6197 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
6198 elem_id, elem_len, left);
6199 return;
6200 }
6201 if (IE_EID_VENDOR == elem_id)
6202 {
6203 /* skipping the VSIE's which we don't want to include or
6204 * it will be included by existing code
6205 */
6206 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
6207#ifdef WLAN_FEATURE_WFD
6208 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
6209#endif
6210 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6211 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6212 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
6213 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6214 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
6215 {
6216 ielen = ptr[1] + 2;
6217 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6218 {
6219 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
6220 *total_ielen += ielen;
6221 }
6222 else
6223 {
6224 hddLog( VOS_TRACE_LEVEL_ERROR,
6225 "IE Length is too big "
6226 "IEs eid=%d elem_len=%d total_ie_lent=%d",
6227 elem_id, elem_len, *total_ielen);
6228 }
6229 }
6230 }
6231
6232 left -= elem_len;
6233 ptr += (elem_len + 2);
6234 }
6235 return;
6236}
6237
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006238#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006239static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6240 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006241#else
6242static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6243 struct cfg80211_beacon_data *params)
6244#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006245{
6246 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306247 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006248 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07006249 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006250
6251 genie = vos_mem_malloc(MAX_GENIE_LEN);
6252
6253 if(genie == NULL) {
6254
6255 return -ENOMEM;
6256 }
6257
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306258 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6259 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006260 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306261 hddLog(LOGE,
6262 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306263 ret = -EINVAL;
6264 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006265 }
6266
6267#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306268 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6269 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
6270 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306271 hddLog(LOGE,
6272 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306273 ret = -EINVAL;
6274 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006275 }
6276#endif
6277
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306278 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6279 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006280 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306281 hddLog(LOGE,
6282 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306283 ret = -EINVAL;
6284 goto done;
6285 }
6286
6287 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
6288 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006289 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07006290 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006291
6292 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6293 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
6294 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6295 {
6296 hddLog(LOGE,
6297 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006298 ret = -EINVAL;
6299 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006300 }
6301
6302 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6303 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6304 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6305 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6306 ==eHAL_STATUS_FAILURE)
6307 {
6308 hddLog(LOGE,
6309 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006310 ret = -EINVAL;
6311 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006312 }
6313
6314 // Added for ProResp IE
6315 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
6316 {
6317 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
6318 u8 probe_rsp_ie_len[3] = {0};
6319 u8 counter = 0;
6320 /* Check Probe Resp Length if it is greater then 255 then Store
6321 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
6322 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
6323 Store More then 255 bytes into One Variable.
6324 */
6325 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6326 {
6327 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6328 {
6329 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6330 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6331 }
6332 else
6333 {
6334 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6335 rem_probe_resp_ie_len = 0;
6336 }
6337 }
6338
6339 rem_probe_resp_ie_len = 0;
6340
6341 if (probe_rsp_ie_len[0] > 0)
6342 {
6343 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6344 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6345 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6346 probe_rsp_ie_len[0], NULL,
6347 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6348 {
6349 hddLog(LOGE,
6350 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006351 ret = -EINVAL;
6352 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006353 }
6354 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6355 }
6356
6357 if (probe_rsp_ie_len[1] > 0)
6358 {
6359 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6360 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6361 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6362 probe_rsp_ie_len[1], NULL,
6363 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6364 {
6365 hddLog(LOGE,
6366 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006367 ret = -EINVAL;
6368 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006369 }
6370 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6371 }
6372
6373 if (probe_rsp_ie_len[2] > 0)
6374 {
6375 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6376 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6377 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6378 probe_rsp_ie_len[2], NULL,
6379 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6380 {
6381 hddLog(LOGE,
6382 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006383 ret = -EINVAL;
6384 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006385 }
6386 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6387 }
6388
6389 if (probe_rsp_ie_len[1] == 0 )
6390 {
6391 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6392 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6393 eANI_BOOLEAN_FALSE) )
6394 {
6395 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006396 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006397 }
6398 }
6399
6400 if (probe_rsp_ie_len[2] == 0 )
6401 {
6402 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6403 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6404 eANI_BOOLEAN_FALSE) )
6405 {
6406 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006407 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006408 }
6409 }
6410
6411 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6412 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6413 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6414 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6415 == eHAL_STATUS_FAILURE)
6416 {
6417 hddLog(LOGE,
6418 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006419 ret = -EINVAL;
6420 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006421 }
6422 }
6423 else
6424 {
6425 // Reset WNI_CFG_PROBE_RSP Flags
6426 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
6427
6428 hddLog(VOS_TRACE_LEVEL_INFO,
6429 "%s: No Probe Response IE received in set beacon",
6430 __func__);
6431 }
6432
6433 // Added for AssocResp IE
6434 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
6435 {
6436 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6437 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
6438 params->assocresp_ies_len, NULL,
6439 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6440 {
6441 hddLog(LOGE,
6442 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006443 ret = -EINVAL;
6444 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006445 }
6446
6447 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6448 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
6449 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6450 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6451 == eHAL_STATUS_FAILURE)
6452 {
6453 hddLog(LOGE,
6454 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006455 ret = -EINVAL;
6456 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006457 }
6458 }
6459 else
6460 {
6461 hddLog(VOS_TRACE_LEVEL_INFO,
6462 "%s: No Assoc Response IE received in set beacon",
6463 __func__);
6464
6465 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6466 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6467 eANI_BOOLEAN_FALSE) )
6468 {
6469 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006470 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006471 }
6472 }
6473
Jeff Johnsone7245742012-09-05 17:12:55 -07006474done:
Jeff Johnson295189b2012-06-20 16:38:30 -07006475 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306476 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006477}
Jeff Johnson295189b2012-06-20 16:38:30 -07006478
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306479/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006480 * FUNCTION: wlan_hdd_validate_operation_channel
6481 * called by wlan_hdd_cfg80211_start_bss() and
6482 * wlan_hdd_cfg80211_set_channel()
6483 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306484 * channel list.
6485 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006486VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006487{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306488
Jeff Johnson295189b2012-06-20 16:38:30 -07006489 v_U32_t num_ch = 0;
6490 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6491 u32 indx = 0;
6492 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306493 v_U8_t fValidChannel = FALSE, count = 0;
6494 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306495
Jeff Johnson295189b2012-06-20 16:38:30 -07006496 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6497
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306498 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006499 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306500 /* Validate the channel */
6501 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006502 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306503 if ( channel == rfChannels[count].channelNum )
6504 {
6505 fValidChannel = TRUE;
6506 break;
6507 }
6508 }
6509 if (fValidChannel != TRUE)
6510 {
6511 hddLog(VOS_TRACE_LEVEL_ERROR,
6512 "%s: Invalid Channel [%d]", __func__, channel);
6513 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006514 }
6515 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306516 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006517 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306518 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6519 valid_ch, &num_ch))
6520 {
6521 hddLog(VOS_TRACE_LEVEL_ERROR,
6522 "%s: failed to get valid channel list", __func__);
6523 return VOS_STATUS_E_FAILURE;
6524 }
6525 for (indx = 0; indx < num_ch; indx++)
6526 {
6527 if (channel == valid_ch[indx])
6528 {
6529 break;
6530 }
6531 }
6532
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306533 if (indx >= num_ch)
6534 {
6535 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6536 {
6537 eCsrBand band;
6538 unsigned int freq;
6539
6540 sme_GetFreqBand(hHal, &band);
6541
6542 if (eCSR_BAND_5G == band)
6543 {
6544#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6545 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6546 {
6547 freq = ieee80211_channel_to_frequency(channel,
6548 IEEE80211_BAND_2GHZ);
6549 }
6550 else
6551 {
6552 freq = ieee80211_channel_to_frequency(channel,
6553 IEEE80211_BAND_5GHZ);
6554 }
6555#else
6556 freq = ieee80211_channel_to_frequency(channel);
6557#endif
6558 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6559 return VOS_STATUS_SUCCESS;
6560 }
6561 }
6562
6563 hddLog(VOS_TRACE_LEVEL_ERROR,
6564 "%s: Invalid Channel [%d]", __func__, channel);
6565 return VOS_STATUS_E_FAILURE;
6566 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006567 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306568
Jeff Johnson295189b2012-06-20 16:38:30 -07006569 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306570
Jeff Johnson295189b2012-06-20 16:38:30 -07006571}
6572
Viral Modi3a32cc52013-02-08 11:14:52 -08006573/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306574 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08006575 * This function is used to set the channel number
6576 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306577static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08006578 struct ieee80211_channel *chan,
6579 enum nl80211_channel_type channel_type
6580 )
6581{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306582 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006583 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006584 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006585 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306586 hdd_context_t *pHddCtx;
6587 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006588
6589 ENTER();
6590
6591 if( NULL == dev )
6592 {
6593 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006594 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006595 return -ENODEV;
6596 }
6597 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306598
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306599 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6600 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6601 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006602 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306603 "%s: device_mode = %s (%d) freq = %d", __func__,
6604 hdd_device_modetoString(pAdapter->device_mode),
6605 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306606
6607 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6608 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306609 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006610 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306611 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006612 }
6613
6614 /*
6615 * Do freq to chan conversion
6616 * TODO: for 11a
6617 */
6618
6619 channel = ieee80211_frequency_to_channel(freq);
6620
6621 /* Check freq range */
6622 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6623 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6624 {
6625 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006626 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006627 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6628 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6629 return -EINVAL;
6630 }
6631
6632 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6633
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306634 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6635 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006636 {
6637 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6638 {
6639 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006640 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006641 return -EINVAL;
6642 }
6643 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6644 "%s: set channel to [%d] for device mode =%d",
6645 __func__, channel,pAdapter->device_mode);
6646 }
6647 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006648 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006649 )
6650 {
6651 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6652 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6653 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6654
6655 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6656 {
6657 /* Link is up then return cant set channel*/
6658 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006659 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006660 return -EINVAL;
6661 }
6662
6663 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6664 pHddStaCtx->conn_info.operationChannel = channel;
6665 pRoamProfile->ChannelInfo.ChannelList =
6666 &pHddStaCtx->conn_info.operationChannel;
6667 }
6668 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006669 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006670 )
6671 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306672 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6673 {
6674 if(VOS_STATUS_SUCCESS !=
6675 wlan_hdd_validate_operation_channel(pAdapter,channel))
6676 {
6677 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006678 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306679 return -EINVAL;
6680 }
6681 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6682 }
6683 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006684 {
6685 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6686
6687 /* If auto channel selection is configured as enable/ 1 then ignore
6688 channel set by supplicant
6689 */
6690 if ( cfg_param->apAutoChannelSelection )
6691 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306692 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6693 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006694 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306695 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6696 __func__, hdd_device_modetoString(pAdapter->device_mode),
6697 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006698 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306699 else
6700 {
6701 if(VOS_STATUS_SUCCESS !=
6702 wlan_hdd_validate_operation_channel(pAdapter,channel))
6703 {
6704 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006705 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306706 return -EINVAL;
6707 }
6708 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6709 }
Viral Modi3a32cc52013-02-08 11:14:52 -08006710 }
6711 }
6712 else
6713 {
6714 hddLog(VOS_TRACE_LEVEL_FATAL,
6715 "%s: Invalid device mode failed to set valid channel", __func__);
6716 return -EINVAL;
6717 }
6718 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306719 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006720}
6721
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306722static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
6723 struct net_device *dev,
6724 struct ieee80211_channel *chan,
6725 enum nl80211_channel_type channel_type
6726 )
6727{
6728 int ret;
6729
6730 vos_ssr_protect(__func__);
6731 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
6732 vos_ssr_unprotect(__func__);
6733
6734 return ret;
6735}
6736
Jeff Johnson295189b2012-06-20 16:38:30 -07006737#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6738static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6739 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006740#else
6741static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6742 struct cfg80211_beacon_data *params,
6743 const u8 *ssid, size_t ssid_len,
6744 enum nl80211_hidden_ssid hidden_ssid)
6745#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006746{
6747 tsap_Config_t *pConfig;
6748 beacon_data_t *pBeacon = NULL;
6749 struct ieee80211_mgmt *pMgmt_frame;
6750 v_U8_t *pIe=NULL;
6751 v_U16_t capab_info;
6752 eCsrAuthType RSNAuthType;
6753 eCsrEncryptionType RSNEncryptType;
6754 eCsrEncryptionType mcRSNEncryptType;
6755 int status = VOS_STATUS_SUCCESS;
6756 tpWLAN_SAPEventCB pSapEventCallback;
6757 hdd_hostapd_state_t *pHostapdState;
6758 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
6759 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306760 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006761 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306762 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07006763 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08006764 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05306765 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07006766 v_BOOL_t MFPCapable = VOS_FALSE;
6767 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05306768 v_BOOL_t sapEnable11AC =
6769 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07006770 ENTER();
6771
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306772 iniConfig = pHddCtx->cfg_ini;
6773
Jeff Johnson295189b2012-06-20 16:38:30 -07006774 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
6775
6776 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6777
6778 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6779
6780 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6781
6782 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
6783
6784 //channel is already set in the set_channel Call back
6785 //pConfig->channel = pCommitConfig->channel;
6786
6787 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306788 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07006789 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
6790
6791 pConfig->dtim_period = pBeacon->dtim_period;
6792
Arif Hussain6d2a3322013-11-17 19:50:10 -08006793 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07006794 pConfig->dtim_period);
6795
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08006796 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07006797 {
6798 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006799 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05306800 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
6801 {
6802 tANI_BOOLEAN restartNeeded;
6803 pConfig->ieee80211d = 1;
6804 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
6805 sme_setRegInfo(hHal, pConfig->countryCode);
6806 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
6807 }
6808 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006809 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07006810 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07006811 pConfig->ieee80211d = 1;
6812 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
6813 sme_setRegInfo(hHal, pConfig->countryCode);
6814 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07006815 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006816 else
6817 {
6818 pConfig->ieee80211d = 0;
6819 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306820 /*
6821 * If auto channel is configured i.e. channel is 0,
6822 * so skip channel validation.
6823 */
6824 if( AUTO_CHANNEL_SELECT != pConfig->channel )
6825 {
6826 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
6827 {
6828 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006829 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306830 return -EINVAL;
6831 }
6832 }
6833 else
6834 {
6835 if(1 != pHddCtx->is_dynamic_channel_range_set)
6836 {
6837 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
6838 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
6839 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
6840 }
6841 pHddCtx->is_dynamic_channel_range_set = 0;
6842 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006843 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006844 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006845 {
6846 pConfig->ieee80211d = 0;
6847 }
6848 pConfig->authType = eSAP_AUTO_SWITCH;
6849
6850 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306851
6852 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07006853 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
6854
6855 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
6856
6857 /*Set wps station to configured*/
6858 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
6859
6860 if(pIe)
6861 {
6862 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
6863 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006864 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07006865 return -EINVAL;
6866 }
6867 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
6868 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006869 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07006870 /* Check 15 bit of WPS IE as it contain information for wps state
6871 * WPS state
6872 */
6873 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
6874 {
6875 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
6876 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
6877 {
6878 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
6879 }
6880 }
6881 }
6882 else
6883 {
6884 pConfig->wps_state = SAP_WPS_DISABLED;
6885 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306886 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07006887
c_hpothufe599e92014-06-16 11:38:55 +05306888 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6889 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6890 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
6891 eCSR_ENCRYPT_TYPE_NONE;
6892
Jeff Johnson295189b2012-06-20 16:38:30 -07006893 pConfig->RSNWPAReqIELength = 0;
6894 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306895 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006896 WLAN_EID_RSN);
6897 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306898 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006899 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6900 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6901 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306902 /* The actual processing may eventually be more extensive than
6903 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07006904 * by the app.
6905 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306906 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006907 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6908 &RSNEncryptType,
6909 &mcRSNEncryptType,
6910 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006911 &MFPCapable,
6912 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006913 pConfig->pRSNWPAReqIE[1]+2,
6914 pConfig->pRSNWPAReqIE );
6915
6916 if( VOS_STATUS_SUCCESS == status )
6917 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306918 /* Now copy over all the security attributes you have
6919 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006920 * */
6921 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6922 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6923 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6924 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306925 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006926 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006927 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6928 }
6929 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306930
Jeff Johnson295189b2012-06-20 16:38:30 -07006931 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6932 pBeacon->tail, pBeacon->tail_len);
6933
6934 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
6935 {
6936 if (pConfig->pRSNWPAReqIE)
6937 {
6938 /*Mixed mode WPA/WPA2*/
6939 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
6940 pConfig->RSNWPAReqIELength += pIe[1] + 2;
6941 }
6942 else
6943 {
6944 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6945 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6946 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306947 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006948 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6949 &RSNEncryptType,
6950 &mcRSNEncryptType,
6951 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006952 &MFPCapable,
6953 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006954 pConfig->pRSNWPAReqIE[1]+2,
6955 pConfig->pRSNWPAReqIE );
6956
6957 if( VOS_STATUS_SUCCESS == status )
6958 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306959 /* Now copy over all the security attributes you have
6960 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006961 * */
6962 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6963 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6964 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6965 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306966 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006967 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006968 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6969 }
6970 }
6971 }
6972
Jeff Johnson4416a782013-03-25 14:17:50 -07006973 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
6974 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
6975 return -EINVAL;
6976 }
6977
Jeff Johnson295189b2012-06-20 16:38:30 -07006978 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
6979
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006980#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006981 if (params->ssid != NULL)
6982 {
6983 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
6984 pConfig->SSIDinfo.ssid.length = params->ssid_len;
6985 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6986 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6987 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006988#else
6989 if (ssid != NULL)
6990 {
6991 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
6992 pConfig->SSIDinfo.ssid.length = ssid_len;
6993 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6994 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6995 }
6996#endif
6997
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306998 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07006999 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307000
Jeff Johnson295189b2012-06-20 16:38:30 -07007001 /* default value */
7002 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7003 pConfig->num_accept_mac = 0;
7004 pConfig->num_deny_mac = 0;
7005
7006 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7007 pBeacon->tail, pBeacon->tail_len);
7008
7009 /* pIe for black list is following form:
7010 type : 1 byte
7011 length : 1 byte
7012 OUI : 4 bytes
7013 acl type : 1 byte
7014 no of mac addr in black list: 1 byte
7015 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307016 */
7017 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007018 {
7019 pConfig->SapMacaddr_acl = pIe[6];
7020 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007021 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007022 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307023 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7024 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007025 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7026 for (i = 0; i < pConfig->num_deny_mac; i++)
7027 {
7028 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7029 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307030 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007031 }
7032 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7033 pBeacon->tail, pBeacon->tail_len);
7034
7035 /* pIe for white list is following form:
7036 type : 1 byte
7037 length : 1 byte
7038 OUI : 4 bytes
7039 acl type : 1 byte
7040 no of mac addr in white list: 1 byte
7041 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307042 */
7043 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007044 {
7045 pConfig->SapMacaddr_acl = pIe[6];
7046 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007047 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007048 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307049 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7050 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007051 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7052 for (i = 0; i < pConfig->num_accept_mac; i++)
7053 {
7054 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7055 acl_entry++;
7056 }
7057 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307058
Jeff Johnson295189b2012-06-20 16:38:30 -07007059 wlan_hdd_set_sapHwmode(pHostapdAdapter);
7060
Jeff Johnsone7245742012-09-05 17:12:55 -07007061#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007062 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307063 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
7064 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05307065 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
7066 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007067 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
7068 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307069 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
7070 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07007071 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307072 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07007073 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307074 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007075
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307076 /* If ACS disable and selected channel <= 14
7077 * OR
7078 * ACS enabled and ACS operating band is choosen as 2.4
7079 * AND
7080 * VHT in 2.4G Disabled
7081 * THEN
7082 * Fallback to 11N mode
7083 */
7084 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
7085 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05307086 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307087 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007088 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307089 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
7090 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007091 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
7092 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007093 }
7094#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307095
Jeff Johnson295189b2012-06-20 16:38:30 -07007096 // ht_capab is not what the name conveys,this is used for protection bitmap
7097 pConfig->ht_capab =
7098 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
7099
7100 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
7101 {
7102 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7103 return -EINVAL;
7104 }
7105
7106 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307107 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07007108 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
7109 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307110 pConfig->obssProtEnabled =
7111 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07007112
Chet Lanctot8cecea22014-02-11 19:09:36 -08007113#ifdef WLAN_FEATURE_11W
7114 pConfig->mfpCapable = MFPCapable;
7115 pConfig->mfpRequired = MFPRequired;
7116 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
7117 pConfig->mfpCapable, pConfig->mfpRequired);
7118#endif
7119
Arif Hussain6d2a3322013-11-17 19:50:10 -08007120 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07007121 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007122 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
7123 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7124 (int)pConfig->channel);
7125 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
7126 pConfig->SapHw_mode, pConfig->privacy,
7127 pConfig->authType);
7128 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
7129 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7130 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7131 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07007132
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307133 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007134 {
7135 //Bss already started. just return.
7136 //TODO Probably it should update some beacon params.
7137 hddLog( LOGE, "Bss Already started...Ignore the request");
7138 EXIT();
7139 return 0;
7140 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307141
Agarwal Ashish51325b52014-06-16 16:50:49 +05307142 if (vos_max_concurrent_connections_reached()) {
7143 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7144 return -EINVAL;
7145 }
7146
Jeff Johnson295189b2012-06-20 16:38:30 -07007147 pConfig->persona = pHostapdAdapter->device_mode;
7148
Peng Xu2446a892014-09-05 17:21:18 +05307149 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
7150 if ( NULL != psmeConfig)
7151 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307152 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05307153 sme_GetConfigParam(hHal, psmeConfig);
7154 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307155#ifdef WLAN_FEATURE_AP_HT40_24G
7156 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7157 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
7158 && pHddCtx->cfg_ini->apHT40_24GEnabled)
7159 {
7160 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
7161 sme_UpdateConfig (hHal, psmeConfig);
7162 }
7163#endif
Peng Xu2446a892014-09-05 17:21:18 +05307164 vos_mem_free(psmeConfig);
7165 }
Peng Xuafc34e32014-09-25 13:23:55 +05307166 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05307167
Jeff Johnson295189b2012-06-20 16:38:30 -07007168 pSapEventCallback = hdd_hostapd_SAPEventCB;
7169 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
7170 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
7171 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007172 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007173 return -EINVAL;
7174 }
7175
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307176 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07007177 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7178
7179 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307180
Jeff Johnson295189b2012-06-20 16:38:30 -07007181 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307182 {
7183 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007184 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07007185 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07007186 VOS_ASSERT(0);
7187 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307188
Jeff Johnson295189b2012-06-20 16:38:30 -07007189 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05307190 /* Initialize WMM configuation */
7191 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307192 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007193
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007194#ifdef WLAN_FEATURE_P2P_DEBUG
7195 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
7196 {
7197 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
7198 {
7199 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7200 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007201 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007202 }
7203 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
7204 {
7205 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7206 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007207 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007208 }
7209 }
7210#endif
7211
Jeff Johnson295189b2012-06-20 16:38:30 -07007212 pHostapdState->bCommit = TRUE;
7213 EXIT();
7214
7215 return 0;
7216}
7217
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007218#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307219static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307220 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007221 struct beacon_parameters *params)
7222{
7223 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307224 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307225 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007226
7227 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307228
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307229 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7230 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
7231 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307232 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
7233 hdd_device_modetoString(pAdapter->device_mode),
7234 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007235
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307236 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7237 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307238 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007239 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307240 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007241 }
7242
Agarwal Ashish51325b52014-06-16 16:50:49 +05307243 if (vos_max_concurrent_connections_reached()) {
7244 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7245 return -EINVAL;
7246 }
7247
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307248 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007249 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007250 )
7251 {
7252 beacon_data_t *old,*new;
7253
7254 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307255
Jeff Johnson295189b2012-06-20 16:38:30 -07007256 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307257 {
7258 hddLog(VOS_TRACE_LEVEL_WARN,
7259 FL("already beacon info added to session(%d)"),
7260 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007261 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307262 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007263
7264 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7265
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307266 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07007267 {
7268 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007269 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007270 return -EINVAL;
7271 }
7272
7273 pAdapter->sessionCtx.ap.beacon = new;
7274
7275 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7276 }
7277
7278 EXIT();
7279 return status;
7280}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307281
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307282static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
7283 struct net_device *dev,
7284 struct beacon_parameters *params)
7285{
7286 int ret;
7287
7288 vos_ssr_protect(__func__);
7289 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
7290 vos_ssr_unprotect(__func__);
7291
7292 return ret;
7293}
7294
7295static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007296 struct net_device *dev,
7297 struct beacon_parameters *params)
7298{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307299 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307300 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7301 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307302 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007303
7304 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307305
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307306 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7307 TRACE_CODE_HDD_CFG80211_SET_BEACON,
7308 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
7309 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7310 __func__, hdd_device_modetoString(pAdapter->device_mode),
7311 pAdapter->device_mode);
7312
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307313 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7314 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307315 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007316 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307317 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007318 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307319
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307320 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007321 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307322 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007323 {
7324 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307325
Jeff Johnson295189b2012-06-20 16:38:30 -07007326 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307327
Jeff Johnson295189b2012-06-20 16:38:30 -07007328 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307329 {
7330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7331 FL("session(%d) old and new heads points to NULL"),
7332 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007333 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307334 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007335
7336 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7337
7338 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307339 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007340 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007341 return -EINVAL;
7342 }
7343
7344 pAdapter->sessionCtx.ap.beacon = new;
7345
7346 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7347 }
7348
7349 EXIT();
7350 return status;
7351}
7352
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307353static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
7354 struct net_device *dev,
7355 struct beacon_parameters *params)
7356{
7357 int ret;
7358
7359 vos_ssr_protect(__func__);
7360 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
7361 vos_ssr_unprotect(__func__);
7362
7363 return ret;
7364}
7365
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007366#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7367
7368#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307369static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007370 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007371#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307372static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007373 struct net_device *dev)
7374#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007375{
7376 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07007377 hdd_context_t *pHddCtx = NULL;
7378 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307379 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307380 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007381
7382 ENTER();
7383
7384 if (NULL == pAdapter)
7385 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307386 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007387 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007388 return -ENODEV;
7389 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007390
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307391 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7392 TRACE_CODE_HDD_CFG80211_STOP_AP,
7393 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307394 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7395 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307396 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007397 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307398 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07007399 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007400
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007401 pScanInfo = &pHddCtx->scan_info;
7402
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307403 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7404 __func__, hdd_device_modetoString(pAdapter->device_mode),
7405 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007406
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307407 ret = wlan_hdd_scan_abort(pAdapter);
7408
Girish Gowli4bf7a632014-06-12 13:42:11 +05307409 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07007410 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7412 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307413
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307414 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07007415 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7417 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08007418
Jeff Johnsone7245742012-09-05 17:12:55 -07007419 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307420 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07007421 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307422 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07007423 }
7424
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05307425 /* Delete all associated STAs before stopping AP/P2P GO */
7426 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05307427 hdd_hostapd_stop(dev);
7428
Jeff Johnson295189b2012-06-20 16:38:30 -07007429 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007430 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007431 )
7432 {
7433 beacon_data_t *old;
7434
7435 old = pAdapter->sessionCtx.ap.beacon;
7436
7437 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307438 {
7439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7440 FL("session(%d) beacon data points to NULL"),
7441 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007442 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307443 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007444
Jeff Johnson295189b2012-06-20 16:38:30 -07007445 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007446
7447 mutex_lock(&pHddCtx->sap_lock);
7448 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7449 {
Jeff Johnson4416a782013-03-25 14:17:50 -07007450 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007451 {
7452 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7453
7454 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7455
7456 if (!VOS_IS_STATUS_SUCCESS(status))
7457 {
7458 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007459 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007460 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307461 }
7462 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007463 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307464 /* BSS stopped, clear the active sessions for this device mode */
7465 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007466 }
7467 mutex_unlock(&pHddCtx->sap_lock);
7468
7469 if(status != VOS_STATUS_SUCCESS)
7470 {
7471 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007472 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007473 return -EINVAL;
7474 }
7475
Jeff Johnson4416a782013-03-25 14:17:50 -07007476 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007477 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
7478 ==eHAL_STATUS_FAILURE)
7479 {
7480 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007481 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007482 }
7483
Jeff Johnson4416a782013-03-25 14:17:50 -07007484 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007485 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7486 eANI_BOOLEAN_FALSE) )
7487 {
7488 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007489 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007490 }
7491
7492 // Reset WNI_CFG_PROBE_RSP Flags
7493 wlan_hdd_reset_prob_rspies(pAdapter);
7494
7495 pAdapter->sessionCtx.ap.beacon = NULL;
7496 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007497#ifdef WLAN_FEATURE_P2P_DEBUG
7498 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7499 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7500 {
7501 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7502 "GO got removed");
7503 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7504 }
7505#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007506 }
7507 EXIT();
7508 return status;
7509}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007510
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307511#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7512static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7513 struct net_device *dev)
7514{
7515 int ret;
7516
7517 vos_ssr_protect(__func__);
7518 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7519 vos_ssr_unprotect(__func__);
7520
7521 return ret;
7522}
7523#else
7524static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7525 struct net_device *dev)
7526{
7527 int ret;
7528
7529 vos_ssr_protect(__func__);
7530 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7531 vos_ssr_unprotect(__func__);
7532
7533 return ret;
7534}
7535#endif
7536
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007537#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7538
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307539static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307540 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007541 struct cfg80211_ap_settings *params)
7542{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307543 hdd_adapter_t *pAdapter;
7544 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307545 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007546
7547 ENTER();
7548
Girish Gowlib143d7a2015-02-18 19:39:55 +05307549 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007550 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05307552 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307553 return -ENODEV;
7554 }
7555
7556 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7557 if (NULL == pAdapter)
7558 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307560 "%s: HDD adapter is Null", __func__);
7561 return -ENODEV;
7562 }
7563
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307564 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7565 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
7566 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307567 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7568 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307570 "%s: HDD adapter magic is invalid", __func__);
7571 return -ENODEV;
7572 }
7573
7574 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307575 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307576 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307577 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307578 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307579 }
7580
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307581 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7582 __func__, hdd_device_modetoString(pAdapter->device_mode),
7583 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307584
7585 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007586 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007587 )
7588 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307589 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007590
7591 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307592
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007593 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307594 {
7595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7596 FL("already beacon info added to session(%d)"),
7597 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007598 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307599 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007600
Girish Gowlib143d7a2015-02-18 19:39:55 +05307601#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7602 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7603 &new,
7604 &params->beacon);
7605#else
7606 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7607 &new,
7608 &params->beacon,
7609 params->dtim_period);
7610#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007611
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307612 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007613 {
7614 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307615 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007616 return -EINVAL;
7617 }
7618 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007619#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007620 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7621#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7622 params->channel, params->channel_type);
7623#else
7624 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7625#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007626#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007627 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
7628 params->ssid_len, params->hidden_ssid);
7629 }
7630
7631 EXIT();
7632 return status;
7633}
7634
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307635static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7636 struct net_device *dev,
7637 struct cfg80211_ap_settings *params)
7638{
7639 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007640
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307641 vos_ssr_protect(__func__);
7642 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
7643 vos_ssr_unprotect(__func__);
7644
7645 return ret;
7646}
7647
7648static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007649 struct net_device *dev,
7650 struct cfg80211_beacon_data *params)
7651{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307652 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307653 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307654 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007655
7656 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307657
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307658 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7659 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7660 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007661 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007662 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307663
7664 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7665 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307666 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007667 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307668 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007669 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007670
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307671 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007672 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307673 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007674 {
7675 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307676
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007677 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307678
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007679 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307680 {
7681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7682 FL("session(%d) beacon data points to NULL"),
7683 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007684 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307685 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007686
7687 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
7688
7689 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307690 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007691 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007692 return -EINVAL;
7693 }
7694
7695 pAdapter->sessionCtx.ap.beacon = new;
7696
7697 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
7698 }
7699
7700 EXIT();
7701 return status;
7702}
7703
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307704static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
7705 struct net_device *dev,
7706 struct cfg80211_beacon_data *params)
7707{
7708 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007709
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307710 vos_ssr_protect(__func__);
7711 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
7712 vos_ssr_unprotect(__func__);
7713
7714 return ret;
7715}
7716
7717#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007718
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307719static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007720 struct net_device *dev,
7721 struct bss_parameters *params)
7722{
7723 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307724 hdd_context_t *pHddCtx;
7725 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007726
7727 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307728
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307729 if (NULL == pAdapter)
7730 {
7731 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7732 "%s: HDD adapter is Null", __func__);
7733 return -ENODEV;
7734 }
7735 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307736 ret = wlan_hdd_validate_context(pHddCtx);
7737 if (0 != ret)
7738 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307739 return ret;
7740 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307741 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7742 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
7743 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307744 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7745 __func__, hdd_device_modetoString(pAdapter->device_mode),
7746 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007747
7748 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007749 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307750 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007751 {
7752 /* ap_isolate == -1 means that in change bss, upper layer doesn't
7753 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307754 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07007755 {
7756 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307757 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007758 }
7759
7760 EXIT();
7761 return 0;
7762}
7763
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307764static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
7765 struct net_device *dev,
7766 struct bss_parameters *params)
7767{
7768 int ret;
7769
7770 vos_ssr_protect(__func__);
7771 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
7772 vos_ssr_unprotect(__func__);
7773
7774 return ret;
7775}
Kiet Lam10841362013-11-01 11:36:50 +05307776/* FUNCTION: wlan_hdd_change_country_code_cd
7777* to wait for contry code completion
7778*/
7779void* wlan_hdd_change_country_code_cb(void *pAdapter)
7780{
7781 hdd_adapter_t *call_back_pAdapter = pAdapter;
7782 complete(&call_back_pAdapter->change_country_code);
7783 return NULL;
7784}
7785
Jeff Johnson295189b2012-06-20 16:38:30 -07007786/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307787 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07007788 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
7789 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307790int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007791 struct net_device *ndev,
7792 enum nl80211_iftype type,
7793 u32 *flags,
7794 struct vif_params *params
7795 )
7796{
7797 struct wireless_dev *wdev;
7798 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007799 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07007800 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007801 tCsrRoamProfile *pRoamProfile = NULL;
7802 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307803 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007804 eMib_dot11DesiredBssType connectedBssType;
7805 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307806 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007807
7808 ENTER();
7809
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307810 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007811 {
7812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7813 "%s: Adapter context is null", __func__);
7814 return VOS_STATUS_E_FAILURE;
7815 }
7816
7817 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7818 if (!pHddCtx)
7819 {
7820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7821 "%s: HDD context is null", __func__);
7822 return VOS_STATUS_E_FAILURE;
7823 }
7824
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307825 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7826 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
7827 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307828 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307829 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007830 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307831 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007832 }
7833
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307834 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7835 __func__, hdd_device_modetoString(pAdapter->device_mode),
7836 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007837
Agarwal Ashish51325b52014-06-16 16:50:49 +05307838 if (vos_max_concurrent_connections_reached()) {
7839 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7840 return -EINVAL;
7841 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307842 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007843 wdev = ndev->ieee80211_ptr;
7844
7845#ifdef WLAN_BTAMP_FEATURE
7846 if((NL80211_IFTYPE_P2P_CLIENT == type)||
7847 (NL80211_IFTYPE_ADHOC == type)||
7848 (NL80211_IFTYPE_AP == type)||
7849 (NL80211_IFTYPE_P2P_GO == type))
7850 {
7851 pHddCtx->isAmpAllowed = VOS_FALSE;
7852 // stop AMP traffic
7853 status = WLANBAP_StopAmp();
7854 if(VOS_STATUS_SUCCESS != status )
7855 {
7856 pHddCtx->isAmpAllowed = VOS_TRUE;
7857 hddLog(VOS_TRACE_LEVEL_FATAL,
7858 "%s: Failed to stop AMP", __func__);
7859 return -EINVAL;
7860 }
7861 }
7862#endif //WLAN_BTAMP_FEATURE
7863 /* Reset the current device mode bit mask*/
7864 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7865
7866 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007867 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07007868 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07007869 )
7870 {
7871 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007872 if (!pWextState)
7873 {
7874 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7875 "%s: pWextState is null", __func__);
7876 return VOS_STATUS_E_FAILURE;
7877 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007878 pRoamProfile = &pWextState->roamProfile;
7879 LastBSSType = pRoamProfile->BSSType;
7880
7881 switch (type)
7882 {
7883 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007884 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007885 hddLog(VOS_TRACE_LEVEL_INFO,
7886 "%s: setting interface Type to INFRASTRUCTURE", __func__);
7887 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07007888#ifdef WLAN_FEATURE_11AC
7889 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
7890 {
7891 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
7892 }
7893#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307894 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07007895 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007896 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007897 //Check for sub-string p2p to confirm its a p2p interface
7898 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307899 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007900 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7901 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7902 }
7903 else
7904 {
7905 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007906 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007907 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007908 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05307909
Jeff Johnson295189b2012-06-20 16:38:30 -07007910 case NL80211_IFTYPE_ADHOC:
7911 hddLog(VOS_TRACE_LEVEL_INFO,
7912 "%s: setting interface Type to ADHOC", __func__);
7913 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
7914 pRoamProfile->phyMode =
7915 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07007916 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007917 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05307918 hdd_set_ibss_ops( pAdapter );
7919 hdd_ibss_init_tx_rx( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007920 break;
7921
7922 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007923 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007924 {
7925 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7926 "%s: setting interface Type to %s", __func__,
7927 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
7928
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007929 //Cancel any remain on channel for GO mode
7930 if (NL80211_IFTYPE_P2P_GO == type)
7931 {
7932 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
7933 }
Mohit Khanna0f232092012-09-11 14:46:08 -07007934 if (NL80211_IFTYPE_AP == type)
7935 {
7936 /* As Loading WLAN Driver one interface being created for p2p device
7937 * address. This will take one HW STA and the max number of clients
7938 * that can connect to softAP will be reduced by one. so while changing
7939 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
7940 * interface as it is not required in SoftAP mode.
7941 */
7942
7943 // Get P2P Adapter
7944 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
7945
7946 if (pP2pAdapter)
7947 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307948 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05307949 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07007950 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
7951 }
7952 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05307953 //Disable IMPS & BMPS for SAP/GO
7954 if(VOS_STATUS_E_FAILURE ==
7955 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
7956 {
7957 //Fail to Exit BMPS
7958 VOS_ASSERT(0);
7959 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05307960
7961 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
7962
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307963#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07007964
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307965 /* A Mutex Lock is introduced while changing the mode to
7966 * protect the concurrent access for the Adapters by TDLS
7967 * module.
7968 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307969 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307970#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007971 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05307972 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07007973 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07007974 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7975 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307976#ifdef FEATURE_WLAN_TDLS
7977 mutex_unlock(&pHddCtx->tdls_lock);
7978#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007979 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
7980 (pConfig->apRandomBssidEnabled))
7981 {
7982 /* To meet Android requirements create a randomized
7983 MAC address of the form 02:1A:11:Fx:xx:xx */
7984 get_random_bytes(&ndev->dev_addr[3], 3);
7985 ndev->dev_addr[0] = 0x02;
7986 ndev->dev_addr[1] = 0x1A;
7987 ndev->dev_addr[2] = 0x11;
7988 ndev->dev_addr[3] |= 0xF0;
7989 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
7990 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08007991 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
7992 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007993 }
7994
Jeff Johnson295189b2012-06-20 16:38:30 -07007995 hdd_set_ap_ops( pAdapter->dev );
7996
Kiet Lam10841362013-11-01 11:36:50 +05307997 /* This is for only SAP mode where users can
7998 * control country through ini.
7999 * P2P GO follows station country code
8000 * acquired during the STA scanning. */
8001 if((NL80211_IFTYPE_AP == type) &&
8002 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
8003 {
8004 int status = 0;
8005 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
8006 "%s: setting country code from INI ", __func__);
8007 init_completion(&pAdapter->change_country_code);
8008 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
8009 (void *)(tSmeChangeCountryCallback)
8010 wlan_hdd_change_country_code_cb,
8011 pConfig->apCntryCode, pAdapter,
8012 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308013 eSIR_FALSE,
8014 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05308015 if (eHAL_STATUS_SUCCESS == status)
8016 {
8017 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308018 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05308019 &pAdapter->change_country_code,
8020 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308021 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05308022 {
8023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308024 FL("SME Timed out while setting country code %ld"),
8025 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08008026
8027 if (pHddCtx->isLogpInProgress)
8028 {
8029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8030 "%s: LOGP in Progress. Ignore!!!", __func__);
8031 return -EAGAIN;
8032 }
Kiet Lam10841362013-11-01 11:36:50 +05308033 }
8034 }
8035 else
8036 {
8037 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008038 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05308039 return -EINVAL;
8040 }
8041 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008042 status = hdd_init_ap_mode(pAdapter);
8043 if(status != VOS_STATUS_SUCCESS)
8044 {
8045 hddLog(VOS_TRACE_LEVEL_FATAL,
8046 "%s: Error initializing the ap mode", __func__);
8047 return -EINVAL;
8048 }
8049 hdd_set_conparam(1);
8050
Jeff Johnson295189b2012-06-20 16:38:30 -07008051 /*interface type changed update in wiphy structure*/
8052 if(wdev)
8053 {
8054 wdev->iftype = type;
8055 pHddCtx->change_iface = type;
8056 }
8057 else
8058 {
8059 hddLog(VOS_TRACE_LEVEL_ERROR,
8060 "%s: ERROR !!!! Wireless dev is NULL", __func__);
8061 return -EINVAL;
8062 }
8063 goto done;
8064 }
8065
8066 default:
8067 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8068 __func__);
8069 return -EOPNOTSUPP;
8070 }
8071 }
8072 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008073 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008074 )
8075 {
8076 switch(type)
8077 {
8078 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008079 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008080 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05308081
8082 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308083#ifdef FEATURE_WLAN_TDLS
8084
8085 /* A Mutex Lock is introduced while changing the mode to
8086 * protect the concurrent access for the Adapters by TDLS
8087 * module.
8088 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308089 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308090#endif
c_hpothu002231a2015-02-05 14:58:51 +05308091 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008092 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008093 //Check for sub-string p2p to confirm its a p2p interface
8094 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008095 {
8096 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8097 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8098 }
8099 else
8100 {
8101 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008102 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008103 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008104 hdd_set_conparam(0);
8105 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008106 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
8107 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308108#ifdef FEATURE_WLAN_TDLS
8109 mutex_unlock(&pHddCtx->tdls_lock);
8110#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308111 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008112 if( VOS_STATUS_SUCCESS != status )
8113 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07008114 /* In case of JB, for P2P-GO, only change interface will be called,
8115 * This is the right place to enable back bmps_imps()
8116 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308117 if (pHddCtx->hdd_wlan_suspended)
8118 {
8119 hdd_set_pwrparams(pHddCtx);
8120 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008121 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008122 goto done;
8123 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008124 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008125 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008126 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8127 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008128 goto done;
8129 default:
8130 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8131 __func__);
8132 return -EOPNOTSUPP;
8133
8134 }
8135
8136 }
8137 else
8138 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308139 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
8140 __func__, hdd_device_modetoString(pAdapter->device_mode),
8141 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008142 return -EOPNOTSUPP;
8143 }
8144
8145
8146 if(pRoamProfile)
8147 {
8148 if ( LastBSSType != pRoamProfile->BSSType )
8149 {
8150 /*interface type changed update in wiphy structure*/
8151 wdev->iftype = type;
8152
8153 /*the BSS mode changed, We need to issue disconnect
8154 if connected or in IBSS disconnect state*/
8155 if ( hdd_connGetConnectedBssType(
8156 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
8157 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
8158 {
8159 /*need to issue a disconnect to CSR.*/
8160 INIT_COMPLETION(pAdapter->disconnect_comp_var);
8161 if( eHAL_STATUS_SUCCESS ==
8162 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
8163 pAdapter->sessionId,
8164 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
8165 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308166 ret = wait_for_completion_interruptible_timeout(
8167 &pAdapter->disconnect_comp_var,
8168 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
8169 if (ret <= 0)
8170 {
8171 hddLog(VOS_TRACE_LEVEL_ERROR,
8172 FL("wait on disconnect_comp_var failed %ld"), ret);
8173 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008174 }
8175 }
8176 }
8177 }
8178
8179done:
8180 /*set bitmask based on updated value*/
8181 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07008182
8183 /* Only STA mode support TM now
8184 * all other mode, TM feature should be disabled */
8185 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
8186 (~VOS_STA & pHddCtx->concurrency_mode) )
8187 {
8188 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
8189 }
8190
Jeff Johnson295189b2012-06-20 16:38:30 -07008191#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308192 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05308193 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07008194 {
8195 //we are ok to do AMP
8196 pHddCtx->isAmpAllowed = VOS_TRUE;
8197 }
8198#endif //WLAN_BTAMP_FEATURE
8199 EXIT();
8200 return 0;
8201}
8202
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308203/*
8204 * FUNCTION: wlan_hdd_cfg80211_change_iface
8205 * wrapper function to protect the actual implementation from SSR.
8206 */
8207int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
8208 struct net_device *ndev,
8209 enum nl80211_iftype type,
8210 u32 *flags,
8211 struct vif_params *params
8212 )
8213{
8214 int ret;
8215
8216 vos_ssr_protect(__func__);
8217 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
8218 vos_ssr_unprotect(__func__);
8219
8220 return ret;
8221}
8222
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008223#ifdef FEATURE_WLAN_TDLS
8224static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
8225 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
8226{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008227 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008228 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308229 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308230 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308231 hdd_adapter_t *pAdapter;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008232
8233 ENTER();
8234
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308235 if (!dev) {
8236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
8237 return -EINVAL;
8238 }
8239
8240 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8241 if (!pAdapter) {
8242 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
8243 return -EINVAL;
8244 }
8245
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308246 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008247 {
8248 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8249 "Invalid arguments");
8250 return -EINVAL;
8251 }
Hoonki Lee27511902013-03-14 18:19:06 -07008252
8253 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
8254 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
8255 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07008257 "%s: TDLS mode is disabled OR not enabled in FW."
8258 MAC_ADDRESS_STR " Request declined.",
8259 __func__, MAC_ADDR_ARRAY(mac));
8260 return -ENOTSUPP;
8261 }
8262
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008263 if (pHddCtx->isLogpInProgress)
8264 {
8265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8266 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05308267 wlan_hdd_tdls_set_link_status(pAdapter,
8268 mac,
8269 eTDLS_LINK_IDLE,
8270 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008271 return -EBUSY;
8272 }
8273
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05308274 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008275
8276 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308277 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008278 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
8279 __func__, MAC_ADDR_ARRAY(mac), update);
8280 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008281 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008282
8283 /* in add station, we accept existing valid staId if there is */
8284 if ((0 == update) &&
8285 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
8286 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008287 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008289 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008290 " link_status %d. staId %d. add station ignored.",
8291 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
8292 return 0;
8293 }
8294 /* in change station, we accept only when staId is valid */
8295 if ((1 == update) &&
8296 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
8297 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
8298 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008300 "%s: " MAC_ADDRESS_STR
8301 " link status %d. staId %d. change station %s.",
8302 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
8303 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
8304 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008305 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008306
8307 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308308 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008309 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8311 "%s: " MAC_ADDRESS_STR
8312 " TDLS setup is ongoing. Request declined.",
8313 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07008314 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008315 }
8316
8317 /* first to check if we reached to maximum supported TDLS peer.
8318 TODO: for now, return -EPERM looks working fine,
8319 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308320 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8321 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008322 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8324 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308325 " TDLS Max peer already connected. Request declined."
8326 " Num of peers (%d), Max allowed (%d).",
8327 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
8328 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008329 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008330 }
8331 else
8332 {
8333 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308334 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008335 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008336 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8338 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
8339 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008340 return -EPERM;
8341 }
8342 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008343 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05308344 wlan_hdd_tdls_set_link_status(pAdapter,
8345 mac,
8346 eTDLS_LINK_CONNECTING,
8347 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008348
Jeff Johnsond75fe012013-04-06 10:53:06 -07008349 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308350 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008351 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008353 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008354 if(StaParams->htcap_present)
8355 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308356 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008357 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008359 "ht_capa->extended_capabilities: %0x",
8360 StaParams->HTCap.extendedHtCapInfo);
8361 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008363 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308364 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008365 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008366 if(StaParams->vhtcap_present)
8367 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308368 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008369 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
8370 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
8371 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
8372 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008373 {
8374 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008376 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308377 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008378 "[%d]: %x ", i, StaParams->supported_rates[i]);
8379 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07008380 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308381 else if ((1 == update) && (NULL == StaParams))
8382 {
8383 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8384 "%s : update is true, but staParams is NULL. Error!", __func__);
8385 return -EPERM;
8386 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008387
8388 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
8389
8390 if (!update)
8391 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308392 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008393 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308394 if (ret != eHAL_STATUS_SUCCESS) {
8395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to add TDLS peer STA"));
8396 return -EPERM;
8397 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008398 }
8399 else
8400 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308401 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008402 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308403 if (ret != eHAL_STATUS_SUCCESS) {
8404 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
8405 return -EPERM;
8406 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008407 }
8408
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308409 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008410 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
8411
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308412 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008413 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308415 "%s: timeout waiting for tdls add station indication %ld",
8416 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008417 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008418 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308419
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008420 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
8421 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008423 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008424 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008425 }
8426
8427 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008428
8429error:
Atul Mittal115287b2014-07-08 13:26:33 +05308430 wlan_hdd_tdls_set_link_status(pAdapter,
8431 mac,
8432 eTDLS_LINK_IDLE,
8433 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008434 return -EPERM;
8435
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008436}
8437#endif
8438
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308439static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008440 struct net_device *dev,
8441 u8 *mac,
8442 struct station_parameters *params)
8443{
8444 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308445 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308446 hdd_context_t *pHddCtx;
8447 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008448 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308449 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008450#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008451 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008452 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308453 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008454#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008455
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308456 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308457
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308458 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308459 if ((NULL == pAdapter))
8460 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308462 "invalid adapter ");
8463 return -EINVAL;
8464 }
8465
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308466 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8467 TRACE_CODE_HDD_CHANGE_STATION,
8468 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05308469 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308470
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308471 ret = wlan_hdd_validate_context(pHddCtx);
8472 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05308473 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308474 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308475 }
8476
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308477 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8478
8479 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008480 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308481 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8482 "invalid HDD station context");
8483 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008484 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008485 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
8486
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008487 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8488 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07008489 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008490 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07008491 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308492 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07008493 WLANTL_STA_AUTHENTICATED);
8494
Gopichand Nakkala29149562013-05-10 21:43:41 +05308495 if (status != VOS_STATUS_SUCCESS)
8496 {
8497 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8498 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8499 return -EINVAL;
8500 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008501 }
8502 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008503 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8504 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308505#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008506 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8507 StaParams.capability = params->capability;
8508 StaParams.uapsd_queues = params->uapsd_queues;
8509 StaParams.max_sp = params->max_sp;
8510
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308511 /* Convert (first channel , number of channels) tuple to
8512 * the total list of channels. This goes with the assumption
8513 * that if the first channel is < 14, then the next channels
8514 * are an incremental of 1 else an incremental of 4 till the number
8515 * of channels.
8516 */
8517 if (0 != params->supported_channels_len) {
8518 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8519 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8520 {
8521 int wifi_chan_index;
8522 StaParams.supported_channels[j] = params->supported_channels[i];
8523 wifi_chan_index =
8524 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8525 no_of_channels = params->supported_channels[i+1];
8526 for(k=1; k <= no_of_channels; k++)
8527 {
8528 StaParams.supported_channels[j+1] =
8529 StaParams.supported_channels[j] + wifi_chan_index;
8530 j+=1;
8531 }
8532 }
8533 StaParams.supported_channels_len = j;
8534 }
8535 vos_mem_copy(StaParams.supported_oper_classes,
8536 params->supported_oper_classes,
8537 params->supported_oper_classes_len);
8538 StaParams.supported_oper_classes_len =
8539 params->supported_oper_classes_len;
8540
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008541 if (0 != params->ext_capab_len)
8542 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8543 sizeof(StaParams.extn_capability));
8544
8545 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008546 {
8547 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008548 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008549 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008550
8551 StaParams.supported_rates_len = params->supported_rates_len;
8552
8553 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8554 * The supported_rates array , for all the structures propogating till Add Sta
8555 * to the firmware has to be modified , if the supplicant (ieee80211) is
8556 * modified to send more rates.
8557 */
8558
8559 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8560 */
8561 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8562 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8563
8564 if (0 != StaParams.supported_rates_len) {
8565 int i = 0;
8566 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8567 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008569 "Supported Rates with Length %d", StaParams.supported_rates_len);
8570 for (i=0; i < StaParams.supported_rates_len; i++)
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 "[%d]: %0x", i, StaParams.supported_rates[i]);
8573 }
8574
8575 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008576 {
8577 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008578 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008579 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008580
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008581 if (0 != params->ext_capab_len ) {
8582 /*Define A Macro : TODO Sunil*/
8583 if ((1<<4) & StaParams.extn_capability[3]) {
8584 isBufSta = 1;
8585 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308586 /* TDLS Channel Switching Support */
8587 if ((1<<6) & StaParams.extn_capability[3]) {
8588 isOffChannelSupported = 1;
8589 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008590 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308591 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8592 &StaParams, isBufSta,
8593 isOffChannelSupported);
8594
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308595 if (VOS_STATUS_SUCCESS != status) {
8596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8597 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8598 return -EINVAL;
8599 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008600 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8601
8602 if (VOS_STATUS_SUCCESS != status) {
8603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8604 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8605 return -EINVAL;
8606 }
8607 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008608#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308609 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008610 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008611 return status;
8612}
8613
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308614static int wlan_hdd_change_station(struct wiphy *wiphy,
8615 struct net_device *dev,
8616 u8 *mac,
8617 struct station_parameters *params)
8618{
8619 int ret;
8620
8621 vos_ssr_protect(__func__);
8622 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
8623 vos_ssr_unprotect(__func__);
8624
8625 return ret;
8626}
8627
Jeff Johnson295189b2012-06-20 16:38:30 -07008628/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308629 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008630 * This function is used to initialize the key information
8631 */
8632#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308633static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008634 struct net_device *ndev,
8635 u8 key_index, bool pairwise,
8636 const u8 *mac_addr,
8637 struct key_params *params
8638 )
8639#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308640static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008641 struct net_device *ndev,
8642 u8 key_index, const u8 *mac_addr,
8643 struct key_params *params
8644 )
8645#endif
8646{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008647 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07008648 tCsrRoamSetKey setKey;
8649 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308650 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008651 v_U32_t roamId= 0xFF;
8652 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008653 hdd_hostapd_state_t *pHostapdState;
8654 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008655 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308656 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008657
8658 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308659
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308660 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8661 TRACE_CODE_HDD_CFG80211_ADD_KEY,
8662 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308663 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8664 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308665 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008666 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308667 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008668 }
8669
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308670 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8671 __func__, hdd_device_modetoString(pAdapter->device_mode),
8672 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008673
8674 if (CSR_MAX_NUM_KEY <= key_index)
8675 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008676 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008677 key_index);
8678
8679 return -EINVAL;
8680 }
8681
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008682 if (CSR_MAX_KEY_LEN < params->key_len)
8683 {
8684 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
8685 params->key_len);
8686
8687 return -EINVAL;
8688 }
8689
8690 hddLog(VOS_TRACE_LEVEL_INFO,
8691 "%s: called with key index = %d & key length %d",
8692 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008693
8694 /*extract key idx, key len and key*/
8695 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8696 setKey.keyId = key_index;
8697 setKey.keyLength = params->key_len;
8698 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
8699
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008700 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07008701 {
8702 case WLAN_CIPHER_SUITE_WEP40:
8703 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
8704 break;
8705
8706 case WLAN_CIPHER_SUITE_WEP104:
8707 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
8708 break;
8709
8710 case WLAN_CIPHER_SUITE_TKIP:
8711 {
8712 u8 *pKey = &setKey.Key[0];
8713 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
8714
8715 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
8716
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008717 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07008718
8719 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008720 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008721 |--------------|----------|----------|
8722 <---16bytes---><--8bytes--><--8bytes-->
8723
8724 */
8725 /*Sme expects the 32 bytes key to be in the below order
8726
8727 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008728 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008729 |--------------|----------|----------|
8730 <---16bytes---><--8bytes--><--8bytes-->
8731 */
8732 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008733 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07008734
8735 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008736 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008737
8738 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008739 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008740
8741
8742 break;
8743 }
8744
8745 case WLAN_CIPHER_SUITE_CCMP:
8746 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
8747 break;
8748
8749#ifdef FEATURE_WLAN_WAPI
8750 case WLAN_CIPHER_SUITE_SMS4:
8751 {
8752 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8753 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
8754 params->key, params->key_len);
8755 return 0;
8756 }
8757#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008758
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008759#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07008760 case WLAN_CIPHER_SUITE_KRK:
8761 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
8762 break;
8763#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008764
8765#ifdef WLAN_FEATURE_11W
8766 case WLAN_CIPHER_SUITE_AES_CMAC:
8767 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07008768 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07008769#endif
8770
Jeff Johnson295189b2012-06-20 16:38:30 -07008771 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008772 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07008773 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308774 status = -EOPNOTSUPP;
8775 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008776 }
8777
8778 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
8779 __func__, setKey.encType);
8780
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008781 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07008782#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8783 (!pairwise)
8784#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008785 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07008786#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008787 )
8788 {
8789 /* set group key*/
8790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8791 "%s- %d: setting Broadcast key",
8792 __func__, __LINE__);
8793 setKey.keyDirection = eSIR_RX_ONLY;
8794 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8795 }
8796 else
8797 {
8798 /* set pairwise key*/
8799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8800 "%s- %d: setting pairwise key",
8801 __func__, __LINE__);
8802 setKey.keyDirection = eSIR_TX_RX;
8803 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8804 }
8805 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
8806 {
8807 setKey.keyDirection = eSIR_TX_RX;
8808 /*Set the group key*/
8809 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8810 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07008811
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008812 if ( 0 != status )
8813 {
8814 hddLog(VOS_TRACE_LEVEL_ERROR,
8815 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308816 status = -EINVAL;
8817 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008818 }
8819 /*Save the keys here and call sme_RoamSetKey for setting
8820 the PTK after peer joins the IBSS network*/
8821 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
8822 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308823 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008824 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05308825 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
8826 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
8827 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008828 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008829 if( pHostapdState->bssState == BSS_START )
8830 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008831 status = WLANSAP_SetKeySta( pVosContext, &setKey);
8832
8833 if ( status != eHAL_STATUS_SUCCESS )
8834 {
8835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8836 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8837 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308838 status = -EINVAL;
8839 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008840 }
8841 }
8842
8843 /* Saving WEP keys */
8844 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
8845 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
8846 {
8847 //Save the wep key in ap context. Issue setkey after the BSS is started.
8848 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8849 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
8850 }
8851 else
8852 {
8853 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008854 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008855 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
8856 }
8857 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008858 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
8859 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008860 {
8861 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8862 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8863
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308864#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8865 if (!pairwise)
8866#else
8867 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8868#endif
8869 {
8870 /* set group key*/
8871 if (pHddStaCtx->roam_info.deferKeyComplete)
8872 {
8873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8874 "%s- %d: Perform Set key Complete",
8875 __func__, __LINE__);
8876 hdd_PerformRoamSetKeyComplete(pAdapter);
8877 }
8878 }
8879
Jeff Johnson295189b2012-06-20 16:38:30 -07008880 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
8881
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08008882 pWextState->roamProfile.Keys.defaultIndex = key_index;
8883
8884
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008885 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008886 params->key, params->key_len);
8887
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308888
Jeff Johnson295189b2012-06-20 16:38:30 -07008889 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8890
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308891 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008892 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308893 __func__, setKey.peerMac[0], setKey.peerMac[1],
8894 setKey.peerMac[2], setKey.peerMac[3],
8895 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008896 setKey.keyDirection);
8897
Nirav Shah4f765af2015-01-21 19:51:30 +05308898 /* Wait for EAPOL M4 before setting key.
8899 * No need to consider Dynamic WEP as we will receive M8.
8900 */
8901 if ( (setKey.encType == eCSR_ENCRYPT_TYPE_AES ||
8902 setKey.encType == eCSR_ENCRYPT_TYPE_TKIP) &&
8903 ( 1
8904#if defined WLAN_FEATURE_VOWIFI_11R
8905 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN
8906 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN_PSK
8907#endif
8908#ifdef FEATURE_WLAN_ESE
8909 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_WPA
8910 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_RSN
8911#endif
8912 ))
Jeff Johnson295189b2012-06-20 16:38:30 -07008913 {
Nirav Shah4f765af2015-01-21 19:51:30 +05308914 vos_status = wlan_hdd_check_ula_done(pAdapter);
8915
8916 if ( vos_status != VOS_STATUS_SUCCESS )
8917 {
8918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008919 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8920 __LINE__, vos_status );
8921
Nirav Shah4f765af2015-01-21 19:51:30 +05308922 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008923
Nirav Shah4f765af2015-01-21 19:51:30 +05308924 status = -EINVAL;
8925 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008926
Nirav Shah4f765af2015-01-21 19:51:30 +05308927 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008928 }
8929
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008930#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308931 /* The supplicant may attempt to set the PTK once pre-authentication
8932 is done. Save the key in the UMAC and include it in the ADD BSS
8933 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008934 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308935 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008936 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308937 hddLog(VOS_TRACE_LEVEL_INFO_MED,
8938 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308939 status = 0;
8940 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308941 }
8942 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
8943 {
8944 hddLog(VOS_TRACE_LEVEL_ERROR,
8945 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308946 status = -EINVAL;
8947 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008948 }
8949#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07008950
8951 /* issue set key request to SME*/
8952 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8953 pAdapter->sessionId, &setKey, &roamId );
8954
8955 if ( 0 != status )
8956 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308957 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008958 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
8959 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308960 status = -EINVAL;
8961 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008962 }
8963
8964
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308965 /* in case of IBSS as there was no information available about WEP keys during
8966 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07008967 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308968 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
8969 !( ( IW_AUTH_KEY_MGMT_802_1X
8970 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07008971 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
8972 )
8973 &&
8974 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
8975 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
8976 )
8977 )
8978 {
8979 setKey.keyDirection = eSIR_RX_ONLY;
8980 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8981
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308982 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008983 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308984 __func__, setKey.peerMac[0], setKey.peerMac[1],
8985 setKey.peerMac[2], setKey.peerMac[3],
8986 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008987 setKey.keyDirection);
8988
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308989 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008990 pAdapter->sessionId, &setKey, &roamId );
8991
8992 if ( 0 != status )
8993 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308994 hddLog(VOS_TRACE_LEVEL_ERROR,
8995 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008996 __func__, status);
8997 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308998 status = -EINVAL;
8999 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009000 }
9001 }
9002 }
9003
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309004end:
9005 /* Need to clear any trace of key value in the memory.
9006 * Thus zero out the memory even though it is local
9007 * variable.
9008 */
9009 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309010 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309011 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009012}
9013
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309014#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9015static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9016 struct net_device *ndev,
9017 u8 key_index, bool pairwise,
9018 const u8 *mac_addr,
9019 struct key_params *params
9020 )
9021#else
9022static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9023 struct net_device *ndev,
9024 u8 key_index, const u8 *mac_addr,
9025 struct key_params *params
9026 )
9027#endif
9028{
9029 int ret;
9030 vos_ssr_protect(__func__);
9031#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9032 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
9033 mac_addr, params);
9034#else
9035 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
9036 params);
9037#endif
9038 vos_ssr_unprotect(__func__);
9039
9040 return ret;
9041}
9042
Jeff Johnson295189b2012-06-20 16:38:30 -07009043/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309044 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009045 * This function is used to get the key information
9046 */
9047#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309048static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309049 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009050 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309051 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009052 const u8 *mac_addr, void *cookie,
9053 void (*callback)(void *cookie, struct key_params*)
9054 )
9055#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309056static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309057 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009058 struct net_device *ndev,
9059 u8 key_index, const u8 *mac_addr, void *cookie,
9060 void (*callback)(void *cookie, struct key_params*)
9061 )
9062#endif
9063{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309064 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309065 hdd_wext_state_t *pWextState = NULL;
9066 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009067 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309068 hdd_context_t *pHddCtx;
9069 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009070
9071 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309072
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309073 if (NULL == pAdapter)
9074 {
9075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9076 "%s: HDD adapter is Null", __func__);
9077 return -ENODEV;
9078 }
9079
9080 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9081 ret = wlan_hdd_validate_context(pHddCtx);
9082 if (0 != ret)
9083 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309084 return ret;
9085 }
9086
9087 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9088 pRoamProfile = &(pWextState->roamProfile);
9089
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309090 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9091 __func__, hdd_device_modetoString(pAdapter->device_mode),
9092 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309093
Jeff Johnson295189b2012-06-20 16:38:30 -07009094 memset(&params, 0, sizeof(params));
9095
9096 if (CSR_MAX_NUM_KEY <= key_index)
9097 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309098 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07009099 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309100 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009101
9102 switch(pRoamProfile->EncryptionType.encryptionType[0])
9103 {
9104 case eCSR_ENCRYPT_TYPE_NONE:
9105 params.cipher = IW_AUTH_CIPHER_NONE;
9106 break;
9107
9108 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
9109 case eCSR_ENCRYPT_TYPE_WEP40:
9110 params.cipher = WLAN_CIPHER_SUITE_WEP40;
9111 break;
9112
9113 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
9114 case eCSR_ENCRYPT_TYPE_WEP104:
9115 params.cipher = WLAN_CIPHER_SUITE_WEP104;
9116 break;
9117
9118 case eCSR_ENCRYPT_TYPE_TKIP:
9119 params.cipher = WLAN_CIPHER_SUITE_TKIP;
9120 break;
9121
9122 case eCSR_ENCRYPT_TYPE_AES:
9123 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
9124 break;
9125
9126 default:
9127 params.cipher = IW_AUTH_CIPHER_NONE;
9128 break;
9129 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309130
c_hpothuaaf19692014-05-17 17:01:48 +05309131 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9132 TRACE_CODE_HDD_CFG80211_GET_KEY,
9133 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309134
Jeff Johnson295189b2012-06-20 16:38:30 -07009135 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
9136 params.seq_len = 0;
9137 params.seq = NULL;
9138 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
9139 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309140 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009141 return 0;
9142}
9143
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309144#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9145static int wlan_hdd_cfg80211_get_key(
9146 struct wiphy *wiphy,
9147 struct net_device *ndev,
9148 u8 key_index, bool pairwise,
9149 const u8 *mac_addr, void *cookie,
9150 void (*callback)(void *cookie, struct key_params*)
9151 )
9152#else
9153static int wlan_hdd_cfg80211_get_key(
9154 struct wiphy *wiphy,
9155 struct net_device *ndev,
9156 u8 key_index, const u8 *mac_addr, void *cookie,
9157 void (*callback)(void *cookie, struct key_params*)
9158 )
9159#endif
9160{
9161 int ret;
9162
9163 vos_ssr_protect(__func__);
9164#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9165 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
9166 mac_addr, cookie, callback);
9167#else
9168 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
9169 callback);
9170#endif
9171 vos_ssr_unprotect(__func__);
9172
9173 return ret;
9174}
9175
Jeff Johnson295189b2012-06-20 16:38:30 -07009176/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309177 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009178 * This function is used to delete the key information
9179 */
9180#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309181static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009182 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309183 u8 key_index,
9184 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009185 const u8 *mac_addr
9186 )
9187#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309188static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009189 struct net_device *ndev,
9190 u8 key_index,
9191 const u8 *mac_addr
9192 )
9193#endif
9194{
9195 int status = 0;
9196
9197 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309198 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009199 //it is observed that this is invalidating peer
9200 //key index whenever re-key is done. This is affecting data link.
9201 //It should be ok to ignore del_key.
9202#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309203 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
9204 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009205 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
9206 tCsrRoamSetKey setKey;
9207 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309208
Jeff Johnson295189b2012-06-20 16:38:30 -07009209 ENTER();
9210
9211 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
9212 __func__,pAdapter->device_mode);
9213
9214 if (CSR_MAX_NUM_KEY <= key_index)
9215 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309216 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009217 key_index);
9218
9219 return -EINVAL;
9220 }
9221
9222 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9223 setKey.keyId = key_index;
9224
9225 if (mac_addr)
9226 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9227 else
9228 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
9229
9230 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
9231
9232 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009233 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309234 )
9235 {
9236
9237 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07009238 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9239 if( pHostapdState->bssState == BSS_START)
9240 {
9241 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309242
Jeff Johnson295189b2012-06-20 16:38:30 -07009243 if ( status != eHAL_STATUS_SUCCESS )
9244 {
9245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9246 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9247 __LINE__, status );
9248 }
9249 }
9250 }
9251 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309252 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07009253 )
9254 {
9255 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9256
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309257 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9258
9259 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009260 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309261 __func__, setKey.peerMac[0], setKey.peerMac[1],
9262 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07009263 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309264 if(pAdapter->sessionCtx.station.conn_info.connState ==
9265 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07009266 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309267 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009268 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309269
Jeff Johnson295189b2012-06-20 16:38:30 -07009270 if ( 0 != status )
9271 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309272 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009273 "%s: sme_RoamSetKey failure, returned %d",
9274 __func__, status);
9275 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9276 return -EINVAL;
9277 }
9278 }
9279 }
9280#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009281 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009282 return status;
9283}
9284
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309285#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9286static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9287 struct net_device *ndev,
9288 u8 key_index,
9289 bool pairwise,
9290 const u8 *mac_addr
9291 )
9292#else
9293static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9294 struct net_device *ndev,
9295 u8 key_index,
9296 const u8 *mac_addr
9297 )
9298#endif
9299{
9300 int ret;
9301
9302 vos_ssr_protect(__func__);
9303#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9304 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
9305 mac_addr);
9306#else
9307 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
9308#endif
9309 vos_ssr_unprotect(__func__);
9310
9311 return ret;
9312}
9313
Jeff Johnson295189b2012-06-20 16:38:30 -07009314/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309315 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009316 * This function is used to set the default tx key index
9317 */
9318#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309319static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009320 struct net_device *ndev,
9321 u8 key_index,
9322 bool unicast, bool multicast)
9323#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309324static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009325 struct net_device *ndev,
9326 u8 key_index)
9327#endif
9328{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309329 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309330 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309331 hdd_wext_state_t *pWextState;
9332 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309333 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009334
9335 ENTER();
9336
Gopichand Nakkala29149562013-05-10 21:43:41 +05309337 if ((NULL == pAdapter))
9338 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309339 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309340 "invalid adapter");
9341 return -EINVAL;
9342 }
9343
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309344 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9345 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
9346 pAdapter->sessionId, key_index));
9347
Gopichand Nakkala29149562013-05-10 21:43:41 +05309348 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9349 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9350
9351 if ((NULL == pWextState) || (NULL == pHddStaCtx))
9352 {
9353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9354 "invalid Wext state or HDD context");
9355 return -EINVAL;
9356 }
9357
Arif Hussain6d2a3322013-11-17 19:50:10 -08009358 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009359 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309360
Jeff Johnson295189b2012-06-20 16:38:30 -07009361 if (CSR_MAX_NUM_KEY <= key_index)
9362 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309363 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009364 key_index);
9365
9366 return -EINVAL;
9367 }
9368
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309369 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9370 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309371 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009372 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309373 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009374 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309375
Jeff Johnson295189b2012-06-20 16:38:30 -07009376 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07009377 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309378 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009379 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309380 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08009381 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309382 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08009383 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07009384 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309385 {
9386 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07009387 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309388
Jeff Johnson295189b2012-06-20 16:38:30 -07009389 tCsrRoamSetKey setKey;
9390 v_U32_t roamId= 0xFF;
9391 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309392
9393 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009394 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309395
Jeff Johnson295189b2012-06-20 16:38:30 -07009396 Keys->defaultIndex = (u8)key_index;
9397 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9398 setKey.keyId = key_index;
9399 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309400
9401 vos_mem_copy(&setKey.Key[0],
9402 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009403 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309404
Gopichand Nakkala29149562013-05-10 21:43:41 +05309405 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309406
9407 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07009408 &pHddStaCtx->conn_info.bssId[0],
9409 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309410
Gopichand Nakkala29149562013-05-10 21:43:41 +05309411 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
9412 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
9413 eCSR_ENCRYPT_TYPE_WEP104)
9414 {
9415 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
9416 even though ap is configured for WEP-40 encryption. In this canse the key length
9417 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
9418 type(104) and switching encryption type to 40*/
9419 pWextState->roamProfile.EncryptionType.encryptionType[0] =
9420 eCSR_ENCRYPT_TYPE_WEP40;
9421 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
9422 eCSR_ENCRYPT_TYPE_WEP40;
9423 }
9424
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309425 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07009426 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309427
Jeff Johnson295189b2012-06-20 16:38:30 -07009428 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309429 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009430 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309431
Jeff Johnson295189b2012-06-20 16:38:30 -07009432 if ( 0 != status )
9433 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309434 hddLog(VOS_TRACE_LEVEL_ERROR,
9435 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009436 status);
9437 return -EINVAL;
9438 }
9439 }
9440 }
9441
9442 /* In SoftAp mode setting key direction for default mode */
9443 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
9444 {
9445 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
9446 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
9447 (eCSR_ENCRYPT_TYPE_AES !=
9448 pWextState->roamProfile.EncryptionType.encryptionType[0])
9449 )
9450 {
9451 /* Saving key direction for default key index to TX default */
9452 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9453 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
9454 }
9455 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309456 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009457 return status;
9458}
9459
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309460#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9461static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9462 struct net_device *ndev,
9463 u8 key_index,
9464 bool unicast, bool multicast)
9465#else
9466static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9467 struct net_device *ndev,
9468 u8 key_index)
9469#endif
9470{
9471 int ret;
9472 vos_ssr_protect(__func__);
9473#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9474 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
9475 multicast);
9476#else
9477 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
9478#endif
9479 vos_ssr_unprotect(__func__);
9480
9481 return ret;
9482}
9483
Jeff Johnson295189b2012-06-20 16:38:30 -07009484/*
9485 * FUNCTION: wlan_hdd_cfg80211_inform_bss
9486 * This function is used to inform the BSS details to nl80211 interface.
9487 */
9488static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
9489 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
9490{
9491 struct net_device *dev = pAdapter->dev;
9492 struct wireless_dev *wdev = dev->ieee80211_ptr;
9493 struct wiphy *wiphy = wdev->wiphy;
9494 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
9495 int chan_no;
9496 int ie_length;
9497 const char *ie;
9498 unsigned int freq;
9499 struct ieee80211_channel *chan;
9500 int rssi = 0;
9501 struct cfg80211_bss *bss = NULL;
9502
9503 ENTER();
9504
9505 if( NULL == pBssDesc )
9506 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009507 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009508 return bss;
9509 }
9510
9511 chan_no = pBssDesc->channelId;
9512 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
9513 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
9514
9515 if( NULL == ie )
9516 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009517 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009518 return bss;
9519 }
9520
9521#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9522 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9523 {
9524 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9525 }
9526 else
9527 {
9528 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9529 }
9530#else
9531 freq = ieee80211_channel_to_frequency(chan_no);
9532#endif
9533
9534 chan = __ieee80211_get_channel(wiphy, freq);
9535
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05309536 if (!chan) {
9537 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
9538 return NULL;
9539 }
9540
Abhishek Singhaee43942014-06-16 18:55:47 +05309541 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07009542
Abhishek Singhaee43942014-06-16 18:55:47 +05309543 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309544 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07009545 pBssDesc->capabilityInfo,
9546 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05309547 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07009548}
9549
9550
9551
9552/*
9553 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
9554 * This function is used to inform the BSS details to nl80211 interface.
9555 */
9556struct cfg80211_bss*
9557wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9558 tSirBssDescription *bss_desc
9559 )
9560{
9561 /*
9562 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9563 already exists in bss data base of cfg80211 for that particular BSS ID.
9564 Using cfg80211_inform_bss_frame to update the bss entry instead of
9565 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9566 now there is no possibility to get the mgmt(probe response) frame from PE,
9567 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9568 cfg80211_inform_bss_frame.
9569 */
9570 struct net_device *dev = pAdapter->dev;
9571 struct wireless_dev *wdev = dev->ieee80211_ptr;
9572 struct wiphy *wiphy = wdev->wiphy;
9573 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009574#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9575 qcom_ie_age *qie_age = NULL;
9576 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9577#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009578 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009579#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009580 const char *ie =
9581 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9582 unsigned int freq;
9583 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309584 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009585 struct cfg80211_bss *bss_status = NULL;
9586 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9587 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009588 hdd_context_t *pHddCtx;
9589 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009590#ifdef WLAN_OPEN_SOURCE
9591 struct timespec ts;
9592#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009593
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309594 ENTER();
9595
Wilson Yangf80a0542013-10-07 13:02:37 -07009596 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9597 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -07009598 if (0 != status)
9599 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009600 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009601 }
9602
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309603 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009604 if (!mgmt)
9605 {
9606 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9607 "%s: memory allocation failed ", __func__);
9608 return NULL;
9609 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009610
Jeff Johnson295189b2012-06-20 16:38:30 -07009611 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07009612
9613#ifdef WLAN_OPEN_SOURCE
9614 /* Android does not want the timestamp from the frame.
9615 Instead it wants a monotonic increasing value */
9616 get_monotonic_boottime(&ts);
9617 mgmt->u.probe_resp.timestamp =
9618 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
9619#else
9620 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009621 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
9622 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07009623
9624#endif
9625
Jeff Johnson295189b2012-06-20 16:38:30 -07009626 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
9627 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009628
9629#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9630 /* GPS Requirement: need age ie per entry. Using vendor specific. */
9631 /* Assuming this is the last IE, copy at the end */
9632 ie_length -=sizeof(qcom_ie_age);
9633 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
9634 qie_age->element_id = QCOM_VENDOR_IE_ID;
9635 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
9636 qie_age->oui_1 = QCOM_OUI1;
9637 qie_age->oui_2 = QCOM_OUI2;
9638 qie_age->oui_3 = QCOM_OUI3;
9639 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
9640 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
9641#endif
9642
Jeff Johnson295189b2012-06-20 16:38:30 -07009643 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05309644 if (bss_desc->fProbeRsp)
9645 {
9646 mgmt->frame_control |=
9647 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
9648 }
9649 else
9650 {
9651 mgmt->frame_control |=
9652 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
9653 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009654
9655#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309656 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009657 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
9658 {
9659 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9660 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309661 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009662 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
9663
9664 {
9665 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9666 }
9667 else
9668 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309669 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
9670 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07009671 kfree(mgmt);
9672 return NULL;
9673 }
9674#else
9675 freq = ieee80211_channel_to_frequency(chan_no);
9676#endif
9677 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009678 /*when the band is changed on the fly using the GUI, three things are done
9679 * 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)
9680 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
9681 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
9682 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
9683 * and discards the channels correponding to previous band and calls back with zero bss results.
9684 * 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
9685 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
9686 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
9687 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
9688 * So drop the bss and continue to next bss.
9689 */
9690 if(chan == NULL)
9691 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309692 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07009693 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009694 return NULL;
9695 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009696 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309697 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07009698 * */
9699 if (( eConnectionState_Associated ==
9700 pAdapter->sessionCtx.station.conn_info.connState ) &&
9701 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
9702 pAdapter->sessionCtx.station.conn_info.bssId,
9703 WNI_CFG_BSSID_LEN)))
9704 {
9705 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
9706 rssi = (pAdapter->rssi * 100);
9707 }
9708 else
9709 {
9710 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
9711 }
9712
Nirav Shah20ac06f2013-12-12 18:14:06 +05309713 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
9714 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
9715 chan->center_freq, (int)(rssi/100));
9716
Jeff Johnson295189b2012-06-20 16:38:30 -07009717 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
9718 frame_len, rssi, GFP_KERNEL);
9719 kfree(mgmt);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309720 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009721 return bss_status;
9722}
9723
9724/*
9725 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
9726 * This function is used to update the BSS data base of CFG8011
9727 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309728struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009729 tCsrRoamInfo *pRoamInfo
9730 )
9731{
9732 tCsrRoamConnectedProfile roamProfile;
9733 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9734 struct cfg80211_bss *bss = NULL;
9735
9736 ENTER();
9737
9738 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
9739 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
9740
9741 if (NULL != roamProfile.pBssDesc)
9742 {
Girish Gowlif4b68022014-08-28 23:18:57 +05309743 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9744 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009745
9746 if (NULL == bss)
9747 {
9748 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
9749 __func__);
9750 }
9751
9752 sme_RoamFreeConnectProfile(hHal, &roamProfile);
9753 }
9754 else
9755 {
9756 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
9757 __func__);
9758 }
9759 return bss;
9760}
9761
9762/*
9763 * FUNCTION: wlan_hdd_cfg80211_update_bss
9764 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309765static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
9766 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07009767 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309768{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309769 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009770 tCsrScanResultInfo *pScanResult;
9771 eHalStatus status = 0;
9772 tScanResultHandle pResult;
9773 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009774 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009775
9776 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309777
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309778 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9779 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
9780 NO_SESSION, pAdapter->sessionId));
9781
Wilson Yangf80a0542013-10-07 13:02:37 -07009782 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9783
9784 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009785 {
Wilson Yangf80a0542013-10-07 13:02:37 -07009786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9787 "%s:LOGP in Progress. Ignore!!!",__func__);
9788 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009789 }
9790
Wilson Yangf80a0542013-10-07 13:02:37 -07009791
9792 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309793 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009794 {
9795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9796 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9797 return VOS_STATUS_E_PERM;
9798 }
9799
9800
Jeff Johnson295189b2012-06-20 16:38:30 -07009801 /*
9802 * start getting scan results and populate cgf80211 BSS database
9803 */
9804 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
9805
9806 /* no scan results */
9807 if (NULL == pResult)
9808 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309809 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
9810 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009811 return status;
9812 }
9813
9814 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
9815
9816 while (pScanResult)
9817 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309818 /*
9819 * cfg80211_inform_bss() is not updating ie field of bss entry, if
9820 * entry already exists in bss data base of cfg80211 for that
9821 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
9822 * bss entry instead of cfg80211_inform_bss, But this call expects
9823 * mgmt packet as input. As of now there is no possibility to get
9824 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07009825 * ieee80211_mgmt(probe response) and passing to c
9826 * fg80211_inform_bss_frame.
9827 * */
9828
9829 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9830 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309831
Jeff Johnson295189b2012-06-20 16:38:30 -07009832
9833 if (NULL == bss_status)
9834 {
9835 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009836 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009837 }
9838 else
9839 {
Yue Maf49ba872013-08-19 12:04:25 -07009840 cfg80211_put_bss(
9841#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
9842 wiphy,
9843#endif
9844 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009845 }
9846
9847 pScanResult = sme_ScanResultGetNext(hHal, pResult);
9848 }
9849
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309850 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07009851
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309852 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009853}
9854
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009855void
9856hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
9857{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309858 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08009859 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009860} /****** end hddPrintMacAddr() ******/
9861
9862void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009863hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009864{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309865 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009866 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009867 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
9868 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
9869 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009870} /****** end hddPrintPmkId() ******/
9871
9872//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
9873//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
9874
9875//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
9876//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
9877
9878#define dump_bssid(bssid) \
9879 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009880 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
9881 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009882 }
9883
9884#define dump_pmkid(pMac, pmkid) \
9885 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009886 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
9887 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009888 }
9889
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009890#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009891/*
9892 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
9893 * This function is used to notify the supplicant of a new PMKSA candidate.
9894 */
9895int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309896 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009897 int index, bool preauth )
9898{
Jeff Johnsone7245742012-09-05 17:12:55 -07009899#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009900 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009901 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009902
9903 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07009904 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009905
9906 if( NULL == pRoamInfo )
9907 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009908 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009909 return -EINVAL;
9910 }
9911
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009912 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
9913 {
9914 dump_bssid(pRoamInfo->bssid);
9915 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009916 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009917 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009918#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309919 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009920}
9921#endif //FEATURE_WLAN_LFR
9922
Yue Maef608272013-04-08 23:09:17 -07009923#ifdef FEATURE_WLAN_LFR_METRICS
9924/*
9925 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
9926 * 802.11r/LFR metrics reporting function to report preauth initiation
9927 *
9928 */
9929#define MAX_LFR_METRICS_EVENT_LENGTH 100
9930VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
9931 tCsrRoamInfo *pRoamInfo)
9932{
9933 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9934 union iwreq_data wrqu;
9935
9936 ENTER();
9937
9938 if (NULL == pAdapter)
9939 {
9940 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9941 return VOS_STATUS_E_FAILURE;
9942 }
9943
9944 /* create the event */
9945 memset(&wrqu, 0, sizeof(wrqu));
9946 memset(metrics_notification, 0, sizeof(metrics_notification));
9947
9948 wrqu.data.pointer = metrics_notification;
9949 wrqu.data.length = scnprintf(metrics_notification,
9950 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
9951 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9952
9953 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9954
9955 EXIT();
9956
9957 return VOS_STATUS_SUCCESS;
9958}
9959
9960/*
9961 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
9962 * 802.11r/LFR metrics reporting function to report preauth completion
9963 * or failure
9964 */
9965VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
9966 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
9967{
9968 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9969 union iwreq_data wrqu;
9970
9971 ENTER();
9972
9973 if (NULL == pAdapter)
9974 {
9975 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9976 return VOS_STATUS_E_FAILURE;
9977 }
9978
9979 /* create the event */
9980 memset(&wrqu, 0, sizeof(wrqu));
9981 memset(metrics_notification, 0, sizeof(metrics_notification));
9982
9983 scnprintf(metrics_notification, sizeof(metrics_notification),
9984 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
9985 MAC_ADDR_ARRAY(pRoamInfo->bssid));
9986
9987 if (1 == preauth_status)
9988 strncat(metrics_notification, " TRUE", 5);
9989 else
9990 strncat(metrics_notification, " FALSE", 6);
9991
9992 wrqu.data.pointer = metrics_notification;
9993 wrqu.data.length = strlen(metrics_notification);
9994
9995 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9996
9997 EXIT();
9998
9999 return VOS_STATUS_SUCCESS;
10000}
10001
10002/*
10003 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
10004 * 802.11r/LFR metrics reporting function to report handover initiation
10005 *
10006 */
10007VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
10008 tCsrRoamInfo *pRoamInfo)
10009{
10010 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10011 union iwreq_data wrqu;
10012
10013 ENTER();
10014
10015 if (NULL == pAdapter)
10016 {
10017 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10018 return VOS_STATUS_E_FAILURE;
10019 }
10020
10021 /* create the event */
10022 memset(&wrqu, 0, sizeof(wrqu));
10023 memset(metrics_notification, 0, sizeof(metrics_notification));
10024
10025 wrqu.data.pointer = metrics_notification;
10026 wrqu.data.length = scnprintf(metrics_notification,
10027 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
10028 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10029
10030 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10031
10032 EXIT();
10033
10034 return VOS_STATUS_SUCCESS;
10035}
10036#endif
10037
Jeff Johnson295189b2012-06-20 16:38:30 -070010038/*
10039 * FUNCTION: hdd_cfg80211_scan_done_callback
10040 * scanning callback function, called after finishing scan
10041 *
10042 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010043static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070010044 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
10045{
10046 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010047 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010049 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010050 struct cfg80211_scan_request *req = NULL;
10051 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010052 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010053 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010054 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010055 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010056
10057 ENTER();
10058
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010059 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10060 if (0 != wlan_hdd_validate_context(pHddCtx)) {
10061 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
10062 goto allow_suspend;
10063 }
10064
10065 pScanInfo = &pHddCtx->scan_info;
10066
Jeff Johnson295189b2012-06-20 16:38:30 -070010067 hddLog(VOS_TRACE_LEVEL_INFO,
10068 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080010069 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010070 __func__, halHandle, pContext, (int) scanId, (int) status);
10071
Kiet Lamac06e2c2013-10-23 16:25:07 +053010072 pScanInfo->mScanPendingCounter = 0;
10073
Jeff Johnson295189b2012-06-20 16:38:30 -070010074 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010075 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010076 &pScanInfo->scan_req_completion_event,
10077 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010078 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070010079 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010080 hddLog(VOS_TRACE_LEVEL_ERROR,
10081 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070010082 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010083 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010084 }
10085
Yue Maef608272013-04-08 23:09:17 -070010086 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010087 {
10088 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010089 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010090 }
10091
10092 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010093 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070010094 {
10095 hddLog(VOS_TRACE_LEVEL_INFO,
10096 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010097 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070010098 (int) scanId);
10099 }
10100
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010101 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010102 pAdapter);
10103
10104 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010105 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010106
10107
10108 /* If any client wait scan result through WEXT
10109 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010110 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070010111 {
10112 /* The other scan request waiting for current scan finish
10113 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010114 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010115 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010116 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070010117 }
10118 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010119 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010120 {
10121 struct net_device *dev = pAdapter->dev;
10122 union iwreq_data wrqu;
10123 int we_event;
10124 char *msg;
10125
10126 memset(&wrqu, '\0', sizeof(wrqu));
10127 we_event = SIOCGIWSCAN;
10128 msg = NULL;
10129 wireless_send_event(dev, we_event, &wrqu, msg);
10130 }
10131 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010132 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010133
10134 /* Get the Scan Req */
10135 req = pAdapter->request;
10136
10137 if (!req)
10138 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010139 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010140 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010141 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010142 }
10143
Jeff Johnson295189b2012-06-20 16:38:30 -070010144 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070010145 /* Scan is no longer pending */
10146 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010147
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010148 /* last_scan_timestamp is used to decide if new scan
10149 * is needed or not on station interface. If last station
10150 * scan time and new station scan time is less then
10151 * last_scan_timestamp ; driver will return cached scan.
10152 */
10153 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
10154 {
10155 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
10156
10157 if ( req->n_channels )
10158 {
10159 for (i = 0; i < req->n_channels ; i++ )
10160 {
10161 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
10162 }
10163 /* store no of channel scanned */
10164 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
10165 }
10166
10167 }
10168
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070010169 /*
10170 * cfg80211_scan_done informing NL80211 about completion
10171 * of scanning
10172 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010173 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
10174 {
10175 aborted = true;
10176 }
10177 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080010178 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010179
Siddharth Bhal76972212014-10-15 16:22:51 +053010180 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
10181 /* Generate new random mac addr for next scan */
10182 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
10183 hdd_processSpoofMacAddrRequest(pHddCtx);
10184 }
10185
Jeff Johnsone7245742012-09-05 17:12:55 -070010186allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010187 /* release the wake lock at the end of the scan*/
10188 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -070010189
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010190 /* Acquire wakelock to handle the case where APP's tries to suspend
10191 * immediatly after the driver gets connect request(i.e after scan)
10192 * from supplicant, this result in app's is suspending and not able
10193 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010194 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010195
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010196#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010197 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010198#endif
10199
Jeff Johnson295189b2012-06-20 16:38:30 -070010200 EXIT();
10201 return 0;
10202}
10203
10204/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053010205 * FUNCTION: hdd_isConnectionInProgress
10206 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010207 *
10208 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010209v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010210{
10211 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10212 hdd_station_ctx_t *pHddStaCtx = NULL;
10213 hdd_adapter_t *pAdapter = NULL;
10214 VOS_STATUS status = 0;
10215 v_U8_t staId = 0;
10216 v_U8_t *staMac = NULL;
10217
c_hpothu9b781ba2013-12-30 20:57:45 +053010218 if (TRUE == pHddCtx->btCoexModeSet)
10219 {
10220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053010221 FL("BTCoex Mode operation in progress"));
10222 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053010223 }
10224
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010225 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10226
10227 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10228 {
10229 pAdapter = pAdapterNode->pAdapter;
10230
10231 if( pAdapter )
10232 {
10233 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010234 "%s: Adapter with device mode %s (%d) exists",
10235 __func__, hdd_device_modetoString(pAdapter->device_mode),
10236 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010237 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053010238 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10239 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
10240 (eConnectionState_Connecting ==
10241 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
10242 {
10243 hddLog(VOS_TRACE_LEVEL_ERROR,
10244 "%s: %p(%d) Connection is in progress", __func__,
10245 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10246 return VOS_TRUE;
10247 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010248 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053010249 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010250 {
10251 hddLog(VOS_TRACE_LEVEL_ERROR,
10252 "%s: %p(%d) Reassociation is in progress", __func__,
10253 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10254 return VOS_TRUE;
10255 }
10256 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010257 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10258 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010259 {
10260 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10261 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010262 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010263 {
10264 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
10265 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010266 "%s: client " MAC_ADDRESS_STR
10267 " is in the middle of WPS/EAPOL exchange.", __func__,
10268 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010269 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010270 }
10271 }
10272 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
10273 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
10274 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010275 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10276 ptSapContext pSapCtx = NULL;
10277 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10278 if(pSapCtx == NULL){
10279 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10280 FL("psapCtx is NULL"));
10281 return VOS_FALSE;
10282 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010283 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
10284 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010285 if ((pSapCtx->aStaInfo[staId].isUsed) &&
10286 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010287 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010288 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010289
10290 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010291 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
10292 "middle of WPS/EAPOL exchange.", __func__,
10293 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010294 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010295 }
10296 }
10297 }
10298 }
10299 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10300 pAdapterNode = pNext;
10301 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053010302 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010303}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010304
10305/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010306 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070010307 * this scan respond to scan trigger and update cfg80211 scan database
10308 * later, scan dump command can be used to recieve scan results
10309 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010310int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010311#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10312 struct net_device *dev,
10313#endif
10314 struct cfg80211_scan_request *request)
10315{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010316 hdd_adapter_t *pAdapter = NULL;
10317 hdd_context_t *pHddCtx = NULL;
10318 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010319 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010320 tCsrScanRequest scanRequest;
10321 tANI_U8 *channelList = NULL, i;
10322 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010323 int status;
10324 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010325 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010326 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010327
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010328#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
10329 struct net_device *dev = NULL;
10330 if (NULL == request)
10331 {
10332 hddLog(VOS_TRACE_LEVEL_ERROR,
10333 "%s: scan req param null", __func__);
10334 return -EINVAL;
10335 }
10336 dev = request->wdev->netdev;
10337#endif
10338
10339 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
10340 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
10341 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10342
Jeff Johnson295189b2012-06-20 16:38:30 -070010343 ENTER();
10344
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010345 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10346 __func__, hdd_device_modetoString(pAdapter->device_mode),
10347 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010348
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010349 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010350 if (0 != status)
10351 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010352 return status;
10353 }
10354
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010355 if (NULL == pwextBuf)
10356 {
10357 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
10358 __func__);
10359 return -EIO;
10360 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010361 cfg_param = pHddCtx->cfg_ini;
10362 pScanInfo = &pHddCtx->scan_info;
10363
Jeff Johnson295189b2012-06-20 16:38:30 -070010364#ifdef WLAN_BTAMP_FEATURE
10365 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010366 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070010367 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010368 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010369 "%s: No scanning when AMP is on", __func__);
10370 return -EOPNOTSUPP;
10371 }
10372#endif
10373 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010374 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010375 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010376 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010377 "%s: Not scanning on device_mode = %s (%d)",
10378 __func__, hdd_device_modetoString(pAdapter->device_mode),
10379 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010380 return -EOPNOTSUPP;
10381 }
10382
10383 if (TRUE == pScanInfo->mScanPending)
10384 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010385 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
10386 {
10387 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
10388 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010389 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010390 }
10391
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010392 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070010393 //Channel and action frame is pending
10394 //Otherwise Cancel Remain On Channel and allow Scan
10395 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010396 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070010397 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010398 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010399 return -EBUSY;
10400 }
10401
Jeff Johnson295189b2012-06-20 16:38:30 -070010402 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
10403 {
10404 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080010405 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010406 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010407 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010408 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
10409 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010410 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010411 "%s: MAX TM Level Scan not allowed", __func__);
10412 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010413 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010414 }
10415 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
10416
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010417 /* Check if scan is allowed at this point of time.
10418 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010419 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010420 {
10421 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
10422 return -EBUSY;
10423 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010424
Jeff Johnson295189b2012-06-20 16:38:30 -070010425 vos_mem_zero( &scanRequest, sizeof(scanRequest));
10426
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010427 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
10428 (int)request->n_ssids);
10429
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010430
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010431 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
10432 * Becasue of this, driver is assuming that this is not wildcard scan and so
10433 * is not aging out the scan results.
10434 */
10435 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010436 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010437 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010438 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010439
10440 if ((request->ssids) && (0 < request->n_ssids))
10441 {
10442 tCsrSSIDInfo *SsidInfo;
10443 int j;
10444 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
10445 /* Allocate num_ssid tCsrSSIDInfo structure */
10446 SsidInfo = scanRequest.SSIDs.SSIDList =
10447 ( tCsrSSIDInfo *)vos_mem_malloc(
10448 request->n_ssids*sizeof(tCsrSSIDInfo));
10449
10450 if(NULL == scanRequest.SSIDs.SSIDList)
10451 {
10452 hddLog(VOS_TRACE_LEVEL_ERROR,
10453 "%s: memory alloc failed SSIDInfo buffer", __func__);
10454 return -ENOMEM;
10455 }
10456
10457 /* copy all the ssid's and their length */
10458 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
10459 {
10460 /* get the ssid length */
10461 SsidInfo->SSID.length = request->ssids[j].ssid_len;
10462 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
10463 SsidInfo->SSID.length);
10464 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
10465 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
10466 j, SsidInfo->SSID.ssId);
10467 }
10468 /* set the scan type to active */
10469 scanRequest.scanType = eSIR_ACTIVE_SCAN;
10470 }
10471 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070010472 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010473 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10474 TRACE_CODE_HDD_CFG80211_SCAN,
10475 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070010476 /* set the scan type to active */
10477 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010478 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010479 else
10480 {
10481 /*Set the scan type to default type, in this case it is ACTIVE*/
10482 scanRequest.scanType = pScanInfo->scan_mode;
10483 }
10484 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
10485 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070010486
10487 /* set BSSType to default type */
10488 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
10489
10490 /*TODO: scan the requested channels only*/
10491
10492 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010493 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070010494 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010495 hddLog(VOS_TRACE_LEVEL_WARN,
10496 "No of Scan Channels exceeded limit: %d", request->n_channels);
10497 request->n_channels = MAX_CHANNEL;
10498 }
10499
10500 hddLog(VOS_TRACE_LEVEL_INFO,
10501 "No of Scan Channels: %d", request->n_channels);
10502
10503
10504 if( request->n_channels )
10505 {
10506 char chList [(request->n_channels*5)+1];
10507 int len;
10508 channelList = vos_mem_malloc( request->n_channels );
10509 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053010510 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010511 hddLog(VOS_TRACE_LEVEL_ERROR,
10512 "%s: memory alloc failed channelList", __func__);
10513 status = -ENOMEM;
10514 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053010515 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010516
10517 for( i = 0, len = 0; i < request->n_channels ; i++ )
10518 {
10519 channelList[i] = request->channels[i]->hw_value;
10520 len += snprintf(chList+len, 5, "%d ", channelList[i]);
10521 }
10522
Nirav Shah20ac06f2013-12-12 18:14:06 +053010523 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010524 "Channel-List: %s ", chList);
10525 }
c_hpothu53512302014-04-15 18:49:53 +053010526
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010527 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
10528 scanRequest.ChannelInfo.ChannelList = channelList;
10529
10530 /* set requestType to full scan */
10531 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10532
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010533 /* if there is back to back scan happening in driver with in
10534 * nDeferScanTimeInterval interval driver should defer new scan request
10535 * and should provide last cached scan results instead of new channel list.
10536 * This rule is not applicable if scan is p2p scan.
10537 * This condition will work only in case when last request no of channels
10538 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053010539 * This should be done only in connected state
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010540 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010541
Agarwal Ashish57e84372014-12-05 18:26:53 +053010542 if ((VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
10543 {
10544 if ( pScanInfo->last_scan_timestamp !=0 &&
10545 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10546 {
10547 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
10548 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
10549 vos_mem_compare(pScanInfo->last_scan_channelList,
10550 channelList, pScanInfo->last_scan_numChannels))
10551 {
10552 hddLog(VOS_TRACE_LEVEL_WARN,
10553 " New and old station scan time differ is less then %u",
10554 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10555
10556 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010557 pAdapter);
10558
Agarwal Ashish57e84372014-12-05 18:26:53 +053010559 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010560 "Return old cached scan as all channels and no of channels are same");
10561
Agarwal Ashish57e84372014-12-05 18:26:53 +053010562 if (0 > ret)
10563 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010564
Agarwal Ashish57e84372014-12-05 18:26:53 +053010565 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010566
10567 status = eHAL_STATUS_SUCCESS;
10568 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053010569 }
10570 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010571 }
10572
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010573 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10574 * search (Flush on both full scan and social scan but not on single
10575 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10576 */
10577
10578 /* Supplicant does single channel scan after 8-way handshake
10579 * and in that case driver shoudnt flush scan results. If
10580 * driver flushes the scan results here and unfortunately if
10581 * the AP doesnt respond to our probe req then association
10582 * fails which is not desired
10583 */
10584
10585 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
10586 {
10587 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
10588 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
10589 pAdapter->sessionId );
10590 }
10591
10592 if( request->ie_len )
10593 {
10594 /* save this for future association (join requires this) */
10595 /*TODO: Array needs to be converted to dynamic allocation,
10596 * as multiple ie.s can be sent in cfg80211_scan_request structure
10597 * CR 597966
10598 */
10599 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
10600 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
10601 pScanInfo->scanAddIE.length = request->ie_len;
10602
10603 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10604 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10605 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010606 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010607 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070010608 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010609 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
10610 memcpy( pwextBuf->roamProfile.addIEScan,
10611 request->ie, request->ie_len);
10612 }
10613 else
10614 {
10615 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
10616 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070010617 }
10618
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010619 }
10620 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
10621 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
10622
10623 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
10624 request->ie_len);
10625 if (pP2pIe != NULL)
10626 {
10627#ifdef WLAN_FEATURE_P2P_DEBUG
10628 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
10629 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
10630 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053010631 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010632 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
10633 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10634 "Go nego completed to Connection is started");
10635 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10636 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053010637 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010638 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
10639 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010640 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010641 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
10642 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10643 "Disconnected state to Connection is started");
10644 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10645 "for 4way Handshake");
10646 }
10647#endif
10648
10649 /* no_cck will be set during p2p find to disable 11b rates */
10650 if(TRUE == request->no_cck)
10651 {
10652 hddLog(VOS_TRACE_LEVEL_INFO,
10653 "%s: This is a P2P Search", __func__);
10654 scanRequest.p2pSearch = 1;
10655
10656 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053010657 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010658 /* set requestType to P2P Discovery */
10659 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
10660 }
10661
10662 /*
10663 Skip Dfs Channel in case of P2P Search
10664 if it is set in ini file
10665 */
10666 if(cfg_param->skipDfsChnlInP2pSearch)
10667 {
10668 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010669 }
10670 else
10671 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010672 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010673 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010674
Agarwal Ashish4f616132013-12-30 23:32:50 +053010675 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010676 }
10677 }
10678
10679 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
10680
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010681#ifdef FEATURE_WLAN_TDLS
10682 /* if tdls disagree scan right now, return immediately.
10683 tdls will schedule the scan when scan is allowed. (return SUCCESS)
10684 or will reject the scan if any TDLS is in progress. (return -EBUSY)
10685 */
10686 status = wlan_hdd_tdls_scan_callback (pAdapter,
10687 wiphy,
10688#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10689 dev,
10690#endif
10691 request);
10692 if(status <= 0)
10693 {
10694 if(!status)
10695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
10696 "scan rejected %d", __func__, status);
10697 else
10698 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
10699 __func__, status);
10700
10701 return status;
10702 }
10703#endif
10704
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010705 /* acquire the wakelock to avoid the apps suspend during the scan. To
10706 * address the following issues.
10707 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
10708 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
10709 * for long time, this result in apps running at full power for long time.
10710 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
10711 * be stuck in full power because of resume BMPS
10712 */
10713 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -070010714
Nirav Shah20ac06f2013-12-12 18:14:06 +053010715 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10716 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010717 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
10718 scanRequest.requestType, scanRequest.scanType,
10719 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053010720 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
10721
Siddharth Bhal76972212014-10-15 16:22:51 +053010722 if (pHddCtx->spoofMacAddr.isEnabled)
10723 {
10724 hddLog(VOS_TRACE_LEVEL_INFO,
10725 "%s: MAC Spoofing enabled for current scan", __func__);
10726 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
10727 * to fill TxBds for probe request during current scan
10728 */
10729 WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
10730 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
10731 }
10732
Jeff Johnsone7245742012-09-05 17:12:55 -070010733 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010734 pAdapter->sessionId, &scanRequest, &scanId,
10735 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070010736
Jeff Johnson295189b2012-06-20 16:38:30 -070010737 if (eHAL_STATUS_SUCCESS != status)
10738 {
10739 hddLog(VOS_TRACE_LEVEL_ERROR,
10740 "%s: sme_ScanRequest returned error %d", __func__, status);
10741 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010742 if(eHAL_STATUS_RESOURCES == status)
10743 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010744 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
10745 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010746 status = -EBUSY;
10747 } else {
10748 status = -EIO;
10749 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010750 hdd_allow_suspend();
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010751
10752#ifdef FEATURE_WLAN_TDLS
10753 wlan_hdd_tdls_scan_done_callback(pAdapter);
10754#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010755 goto free_mem;
10756 }
10757
10758 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010759 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070010760 pAdapter->request = request;
10761 pScanInfo->scanId = scanId;
10762
10763 complete(&pScanInfo->scan_req_completion_event);
10764
10765free_mem:
10766 if( scanRequest.SSIDs.SSIDList )
10767 {
10768 vos_mem_free(scanRequest.SSIDs.SSIDList);
10769 }
10770
10771 if( channelList )
10772 vos_mem_free( channelList );
10773
10774 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010775 return status;
10776}
10777
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010778int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
10779#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10780 struct net_device *dev,
10781#endif
10782 struct cfg80211_scan_request *request)
10783{
10784 int ret;
10785
10786 vos_ssr_protect(__func__);
10787 ret = __wlan_hdd_cfg80211_scan(wiphy,
10788#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10789 dev,
10790#endif
10791 request);
10792 vos_ssr_unprotect(__func__);
10793
10794 return ret;
10795}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010796
10797void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
10798{
10799 v_U8_t iniDot11Mode =
10800 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
10801 eHddDot11Mode hddDot11Mode = iniDot11Mode;
10802
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010803 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
10804 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010805 switch ( iniDot11Mode )
10806 {
10807 case eHDD_DOT11_MODE_AUTO:
10808 case eHDD_DOT11_MODE_11ac:
10809 case eHDD_DOT11_MODE_11ac_ONLY:
10810#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053010811 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
10812 sme_IsFeatureSupportedByFW(DOT11AC) )
10813 hddDot11Mode = eHDD_DOT11_MODE_11ac;
10814 else
10815 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010816#else
10817 hddDot11Mode = eHDD_DOT11_MODE_11n;
10818#endif
10819 break;
10820 case eHDD_DOT11_MODE_11n:
10821 case eHDD_DOT11_MODE_11n_ONLY:
10822 hddDot11Mode = eHDD_DOT11_MODE_11n;
10823 break;
10824 default:
10825 hddDot11Mode = iniDot11Mode;
10826 break;
10827 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010828#ifdef WLAN_FEATURE_AP_HT40_24G
10829 if (operationChannel > SIR_11B_CHANNEL_END)
10830#endif
10831 {
10832 /* This call decides required channel bonding mode */
10833 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010834 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
10835 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010836 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010837}
10838
Jeff Johnson295189b2012-06-20 16:38:30 -070010839/*
10840 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010841 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010842 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010843int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010844 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010845{
10846 int status = 0;
10847 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080010848 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010849 v_U32_t roamId;
10850 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070010851 eCsrAuthType RSNAuthType;
10852
10853 ENTER();
10854
10855 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080010856 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10857
10858 status = wlan_hdd_validate_context(pHddCtx);
10859 if (status)
10860 {
Yue Mae36e3552014-03-05 17:06:20 -080010861 return status;
10862 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010863
Jeff Johnson295189b2012-06-20 16:38:30 -070010864 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
10865 {
10866 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
10867 return -EINVAL;
10868 }
10869
10870 pRoamProfile = &pWextState->roamProfile;
10871
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010872 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070010873 {
Jeff Johnsone7245742012-09-05 17:12:55 -070010874 hdd_station_ctx_t *pHddStaCtx;
10875 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010876
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010877 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070010878 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
10879 {
10880 /*QoS not enabled in cfg file*/
10881 pRoamProfile->uapsd_mask = 0;
10882 }
10883 else
10884 {
10885 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010886 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070010887 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
10888 }
10889
10890 pRoamProfile->SSIDs.numOfSSIDs = 1;
10891 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
10892 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010893 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070010894 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
10895 ssid, ssid_len);
10896
10897 if (bssid)
10898 {
10899 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
10900 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
10901 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010902 /* Save BSSID in seperate variable as well, as RoamProfile
10903 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070010904 case of join failure we should send valid BSSID to supplicant
10905 */
10906 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
10907 WNI_CFG_BSSID_LEN);
10908 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070010909 else
10910 {
10911 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
10912 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010913
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010914 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
10915 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010916 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
10917 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010918 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010919 /*set gen ie*/
10920 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
10921 /*set auth*/
10922 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
10923 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010924#ifdef FEATURE_WLAN_WAPI
10925 if (pAdapter->wapi_info.nWapiMode)
10926 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010927 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010928 switch (pAdapter->wapi_info.wapiAuthMode)
10929 {
10930 case WAPI_AUTH_MODE_PSK:
10931 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010932 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010933 pAdapter->wapi_info.wapiAuthMode);
10934 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
10935 break;
10936 }
10937 case WAPI_AUTH_MODE_CERT:
10938 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010939 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010940 pAdapter->wapi_info.wapiAuthMode);
10941 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
10942 break;
10943 }
10944 } // End of switch
10945 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
10946 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
10947 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010948 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010949 pRoamProfile->AuthType.numEntries = 1;
10950 pRoamProfile->EncryptionType.numEntries = 1;
10951 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10952 pRoamProfile->mcEncryptionType.numEntries = 1;
10953 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10954 }
10955 }
10956#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010957#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010958 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010959 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10960 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
10961 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010962 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
10963 sizeof (tSirGtkOffloadParams));
10964 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010965 }
10966#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010967 pRoamProfile->csrPersona = pAdapter->device_mode;
10968
Jeff Johnson32d95a32012-09-10 13:15:23 -070010969 if( operatingChannel )
10970 {
10971 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
10972 pRoamProfile->ChannelInfo.numOfChannels = 1;
10973 }
Chet Lanctot186b5732013-03-18 10:26:30 -070010974 else
10975 {
10976 pRoamProfile->ChannelInfo.ChannelList = NULL;
10977 pRoamProfile->ChannelInfo.numOfChannels = 0;
10978 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010979 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
10980 {
10981 hdd_select_cbmode(pAdapter,operatingChannel);
10982 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010983
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010984 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
10985 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010986 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010987 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010988 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
10989 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010990 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10991 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053010992 {
10993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10994 "%s: Set HDD connState to eConnectionState_Connecting",
10995 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010996 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
10997 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053010998 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010999 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011000 pAdapter->sessionId, pRoamProfile, &roamId);
11001
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011002 if ((eHAL_STATUS_SUCCESS != status) &&
11003 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11004 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011005
11006 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011007 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
11008 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
11009 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011010 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011011 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011012 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011013
11014 pRoamProfile->ChannelInfo.ChannelList = NULL;
11015 pRoamProfile->ChannelInfo.numOfChannels = 0;
11016
Jeff Johnson295189b2012-06-20 16:38:30 -070011017 }
11018 else
11019 {
11020 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
11021 return -EINVAL;
11022 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011023 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011024 return status;
11025}
11026
11027/*
11028 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
11029 * This function is used to set the authentication type (OPEN/SHARED).
11030 *
11031 */
11032static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
11033 enum nl80211_auth_type auth_type)
11034{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011035 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011036 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11037
11038 ENTER();
11039
11040 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011041 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070011042 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011043 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011044 hddLog(VOS_TRACE_LEVEL_INFO,
11045 "%s: set authentication type to AUTOSWITCH", __func__);
11046 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
11047 break;
11048
11049 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011050#ifdef WLAN_FEATURE_VOWIFI_11R
11051 case NL80211_AUTHTYPE_FT:
11052#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011053 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011054 "%s: set authentication type to OPEN", __func__);
11055 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11056 break;
11057
11058 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011059 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011060 "%s: set authentication type to SHARED", __func__);
11061 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
11062 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011063#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011064 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011065 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011066 "%s: set authentication type to CCKM WPA", __func__);
11067 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
11068 break;
11069#endif
11070
11071
11072 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011073 hddLog(VOS_TRACE_LEVEL_ERROR,
11074 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011075 auth_type);
11076 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
11077 return -EINVAL;
11078 }
11079
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011080 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011081 pHddStaCtx->conn_info.authType;
11082 return 0;
11083}
11084
11085/*
11086 * FUNCTION: wlan_hdd_set_akm_suite
11087 * This function is used to set the key mgmt type(PSK/8021x).
11088 *
11089 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011090static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011091 u32 key_mgmt
11092 )
11093{
11094 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11095 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053011096 /* Should be in ieee802_11_defs.h */
11097#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
11098#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070011099 /*set key mgmt type*/
11100 switch(key_mgmt)
11101 {
11102 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053011103 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011104#ifdef WLAN_FEATURE_VOWIFI_11R
11105 case WLAN_AKM_SUITE_FT_PSK:
11106#endif
11107 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070011108 __func__);
11109 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
11110 break;
11111
11112 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053011113 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011114#ifdef WLAN_FEATURE_VOWIFI_11R
11115 case WLAN_AKM_SUITE_FT_8021X:
11116#endif
11117 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070011118 __func__);
11119 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11120 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011121#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011122#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
11123#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
11124 case WLAN_AKM_SUITE_CCKM:
11125 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
11126 __func__);
11127 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
11128 break;
11129#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070011130#ifndef WLAN_AKM_SUITE_OSEN
11131#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
11132 case WLAN_AKM_SUITE_OSEN:
11133 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
11134 __func__);
11135 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11136 break;
11137#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011138
11139 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011140 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011141 __func__, key_mgmt);
11142 return -EINVAL;
11143
11144 }
11145 return 0;
11146}
11147
11148/*
11149 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011150 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070011151 * (NONE/WEP40/WEP104/TKIP/CCMP).
11152 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011153static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
11154 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070011155 bool ucast
11156 )
11157{
11158 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011159 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011160 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11161
11162 ENTER();
11163
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011164 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011165 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011166 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070011167 __func__, cipher);
11168 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11169 }
11170 else
11171 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011172
Jeff Johnson295189b2012-06-20 16:38:30 -070011173 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011174 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011175 {
11176 case IW_AUTH_CIPHER_NONE:
11177 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11178 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011179
Jeff Johnson295189b2012-06-20 16:38:30 -070011180 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011181 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070011182 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011183
Jeff Johnson295189b2012-06-20 16:38:30 -070011184 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011185 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070011186 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011187
Jeff Johnson295189b2012-06-20 16:38:30 -070011188 case WLAN_CIPHER_SUITE_TKIP:
11189 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
11190 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011191
Jeff Johnson295189b2012-06-20 16:38:30 -070011192 case WLAN_CIPHER_SUITE_CCMP:
11193 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11194 break;
11195#ifdef FEATURE_WLAN_WAPI
11196 case WLAN_CIPHER_SUITE_SMS4:
11197 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
11198 break;
11199#endif
11200
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011201#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011202 case WLAN_CIPHER_SUITE_KRK:
11203 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
11204 break;
11205#endif
11206 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011207 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011208 __func__, cipher);
11209 return -EOPNOTSUPP;
11210 }
11211 }
11212
11213 if (ucast)
11214 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011215 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011216 __func__, encryptionType);
11217 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11218 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011219 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011220 encryptionType;
11221 }
11222 else
11223 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011224 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011225 __func__, encryptionType);
11226 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
11227 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
11228 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
11229 }
11230
11231 return 0;
11232}
11233
11234
11235/*
11236 * FUNCTION: wlan_hdd_cfg80211_set_ie
11237 * This function is used to parse WPA/RSN IE's.
11238 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011239int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
11240 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070011241 size_t ie_len
11242 )
11243{
11244 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11245 u8 *genie = ie;
11246 v_U16_t remLen = ie_len;
11247#ifdef FEATURE_WLAN_WAPI
11248 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
11249 u16 *tmp;
11250 v_U16_t akmsuiteCount;
11251 int *akmlist;
11252#endif
11253 ENTER();
11254
11255 /* clear previous assocAddIE */
11256 pWextState->assocAddIE.length = 0;
11257 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011258 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011259
11260 while (remLen >= 2)
11261 {
11262 v_U16_t eLen = 0;
11263 v_U8_t elementId;
11264 elementId = *genie++;
11265 eLen = *genie++;
11266 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011267
Arif Hussain6d2a3322013-11-17 19:50:10 -080011268 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070011269 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011270
11271 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070011272 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011273 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011274 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 -070011275 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011276 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011277 "%s: Invalid WPA IE", __func__);
11278 return -EINVAL;
11279 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011280 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070011281 {
11282 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011283 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011284 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011285
Jeff Johnson295189b2012-06-20 16:38:30 -070011286 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11287 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011288 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
11289 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011290 VOS_ASSERT(0);
11291 return -ENOMEM;
11292 }
11293 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11294 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11295 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011296
Jeff Johnson295189b2012-06-20 16:38:30 -070011297 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
11298 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11299 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11300 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011301 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
11302 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011303 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
11304 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11305 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
11306 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
11307 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
11308 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011309 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053011310 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011311 {
11312 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011313 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011314 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011315
Jeff Johnson295189b2012-06-20 16:38:30 -070011316 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11317 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011318 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11319 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011320 VOS_ASSERT(0);
11321 return -ENOMEM;
11322 }
11323 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11324 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11325 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011326
Jeff Johnson295189b2012-06-20 16:38:30 -070011327 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11328 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11329 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011330#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011331 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
11332 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011333 /*Consider WFD IE, only for P2P Client */
11334 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11335 {
11336 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011337 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011338 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011339
Jeff Johnson295189b2012-06-20 16:38:30 -070011340 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11341 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011342 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11343 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011344 VOS_ASSERT(0);
11345 return -ENOMEM;
11346 }
11347 // WFD IE is saved to Additional IE ; it should be accumulated to handle
11348 // WPS IE + P2P IE + WFD IE
11349 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11350 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011351
Jeff Johnson295189b2012-06-20 16:38:30 -070011352 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11353 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11354 }
11355#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011356 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011357 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011358 HS20_OUI_TYPE_SIZE)) )
11359 {
11360 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011361 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011362 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011363
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011364 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11365 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011366 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11367 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011368 VOS_ASSERT(0);
11369 return -ENOMEM;
11370 }
11371 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11372 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011373
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011374 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11375 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11376 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011377 /* Appending OSEN Information Element in Assiciation Request */
11378 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
11379 OSEN_OUI_TYPE_SIZE)) )
11380 {
11381 v_U16_t curAddIELen = pWextState->assocAddIE.length;
11382 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
11383 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011384
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011385 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11386 {
11387 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11388 "Need bigger buffer space");
11389 VOS_ASSERT(0);
11390 return -ENOMEM;
11391 }
11392 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11393 pWextState->assocAddIE.length += eLen + 2;
11394
11395 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
11396 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11397 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11398 }
11399
11400 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011401 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
11402
11403 /* populating as ADDIE in beacon frames */
11404 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11405 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
11406 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
11407 {
11408 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11409 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
11410 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11411 {
11412 hddLog(LOGE,
11413 "Coldn't pass "
11414 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
11415 }
11416 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
11417 else
11418 hddLog(LOGE,
11419 "Could not pass on "
11420 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
11421
11422 /* IBSS mode doesn't contain params->proberesp_ies still
11423 beaconIE's need to be populated in probe response frames */
11424 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
11425 {
11426 u16 rem_probe_resp_ie_len = eLen + 2;
11427 u8 probe_rsp_ie_len[3] = {0};
11428 u8 counter = 0;
11429
11430 /* Check Probe Resp Length if it is greater then 255 then
11431 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
11432 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
11433 not able Store More then 255 bytes into One Variable */
11434
11435 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
11436 {
11437 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
11438 {
11439 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
11440 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
11441 }
11442 else
11443 {
11444 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
11445 rem_probe_resp_ie_len = 0;
11446 }
11447 }
11448
11449 rem_probe_resp_ie_len = 0;
11450
11451 if (probe_rsp_ie_len[0] > 0)
11452 {
11453 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11454 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
11455 (tANI_U8*)(genie - 2),
11456 probe_rsp_ie_len[0], NULL,
11457 eANI_BOOLEAN_FALSE)
11458 == eHAL_STATUS_FAILURE)
11459 {
11460 hddLog(LOGE,
11461 "Could not pass"
11462 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
11463 }
11464 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
11465 }
11466
11467 if (probe_rsp_ie_len[1] > 0)
11468 {
11469 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11470 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
11471 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11472 probe_rsp_ie_len[1], NULL,
11473 eANI_BOOLEAN_FALSE)
11474 == eHAL_STATUS_FAILURE)
11475 {
11476 hddLog(LOGE,
11477 "Could not pass"
11478 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
11479 }
11480 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
11481 }
11482
11483 if (probe_rsp_ie_len[2] > 0)
11484 {
11485 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11486 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
11487 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11488 probe_rsp_ie_len[2], NULL,
11489 eANI_BOOLEAN_FALSE)
11490 == eHAL_STATUS_FAILURE)
11491 {
11492 hddLog(LOGE,
11493 "Could not pass"
11494 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
11495 }
11496 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
11497 }
11498
11499 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11500 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
11501 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11502 {
11503 hddLog(LOGE,
11504 "Could not pass"
11505 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
11506 }
11507 }
11508 else
11509 {
11510 // Reset WNI_CFG_PROBE_RSP Flags
11511 wlan_hdd_reset_prob_rspies(pAdapter);
11512
11513 hddLog(VOS_TRACE_LEVEL_INFO,
11514 "%s: No Probe Response IE received in set beacon",
11515 __func__);
11516 }
11517 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011518 break;
11519 case DOT11F_EID_RSN:
11520 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11521 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11522 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11523 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11524 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11525 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011526 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
11527 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011528 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011529 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011530 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011531 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011532
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011533 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11534 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011535 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11536 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011537 VOS_ASSERT(0);
11538 return -ENOMEM;
11539 }
11540 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11541 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011542
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011543 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11544 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11545 break;
11546 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011547#ifdef FEATURE_WLAN_WAPI
11548 case WLAN_EID_WAPI:
11549 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011550 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011551 pAdapter->wapi_info.nWapiMode);
11552 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011553 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070011554 akmsuiteCount = WPA_GET_LE16(tmp);
11555 tmp = tmp + 1;
11556 akmlist = (int *)(tmp);
11557 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
11558 {
11559 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
11560 }
11561 else
11562 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011563 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070011564 VOS_ASSERT(0);
11565 return -EINVAL;
11566 }
11567
11568 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
11569 {
11570 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011571 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011572 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011573 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011574 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011575 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011576 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011577 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011578 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
11579 }
11580 break;
11581#endif
11582 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011583 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011584 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011585 /* when Unknown IE is received we should break and continue
11586 * to the next IE in the buffer instead we were returning
11587 * so changing this to break */
11588 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011589 }
11590 genie += eLen;
11591 remLen -= eLen;
11592 }
11593 EXIT();
11594 return 0;
11595}
11596
11597/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053011598 * FUNCTION: hdd_isWPAIEPresent
11599 * Parse the received IE to find the WPA IE
11600 *
11601 */
11602static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
11603{
11604 v_U8_t eLen = 0;
11605 v_U16_t remLen = ie_len;
11606 v_U8_t elementId = 0;
11607
11608 while (remLen >= 2)
11609 {
11610 elementId = *ie++;
11611 eLen = *ie++;
11612 remLen -= 2;
11613 if (eLen > remLen)
11614 {
11615 hddLog(VOS_TRACE_LEVEL_ERROR,
11616 "%s: IE length is wrong %d", __func__, eLen);
11617 return FALSE;
11618 }
11619 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
11620 {
11621 /* OUI - 0x00 0X50 0XF2
11622 WPA Information Element - 0x01
11623 WPA version - 0x01*/
11624 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
11625 return TRUE;
11626 }
11627 ie += eLen;
11628 remLen -= eLen;
11629 }
11630 return FALSE;
11631}
11632
11633/*
Jeff Johnson295189b2012-06-20 16:38:30 -070011634 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011635 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011636 * parameters during connect operation.
11637 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011638int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011639 struct cfg80211_connect_params *req
11640 )
11641{
11642 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011643 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011644 ENTER();
11645
11646 /*set wpa version*/
11647 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
11648
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011649 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011650 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053011651 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011652 {
11653 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11654 }
11655 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
11656 {
11657 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11658 }
11659 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011660
11661 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011662 pWextState->wpaVersion);
11663
11664 /*set authentication type*/
11665 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
11666
11667 if (0 > status)
11668 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011669 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011670 "%s: failed to set authentication type ", __func__);
11671 return status;
11672 }
11673
11674 /*set key mgmt type*/
11675 if (req->crypto.n_akm_suites)
11676 {
11677 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
11678 if (0 > status)
11679 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011680 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070011681 __func__);
11682 return status;
11683 }
11684 }
11685
11686 /*set pairwise cipher type*/
11687 if (req->crypto.n_ciphers_pairwise)
11688 {
11689 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
11690 req->crypto.ciphers_pairwise[0], true);
11691 if (0 > status)
11692 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011693 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011694 "%s: failed to set unicast cipher type", __func__);
11695 return status;
11696 }
11697 }
11698 else
11699 {
11700 /*Reset previous cipher suite to none*/
11701 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
11702 if (0 > status)
11703 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011704 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011705 "%s: failed to set unicast cipher type", __func__);
11706 return status;
11707 }
11708 }
11709
11710 /*set group cipher type*/
11711 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
11712 false);
11713
11714 if (0 > status)
11715 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011716 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070011717 __func__);
11718 return status;
11719 }
11720
Chet Lanctot186b5732013-03-18 10:26:30 -070011721#ifdef WLAN_FEATURE_11W
11722 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
11723#endif
11724
Jeff Johnson295189b2012-06-20 16:38:30 -070011725 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
11726 if (req->ie_len)
11727 {
11728 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
11729 if ( 0 > status)
11730 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011731 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011732 __func__);
11733 return status;
11734 }
11735 }
11736
11737 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011738 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011739 {
11740 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
11741 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
11742 )
11743 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011744 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070011745 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
11746 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011747 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011748 __func__);
11749 return -EOPNOTSUPP;
11750 }
11751 else
11752 {
11753 u8 key_len = req->key_len;
11754 u8 key_idx = req->key_idx;
11755
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011756 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011757 && (CSR_MAX_NUM_KEY > key_idx)
11758 )
11759 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011760 hddLog(VOS_TRACE_LEVEL_INFO,
11761 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011762 __func__, key_idx, key_len);
11763 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011764 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011765 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011766 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011767 (u8)key_len;
11768 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
11769 }
11770 }
11771 }
11772 }
11773
11774 return status;
11775}
11776
11777/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011778 * FUNCTION: wlan_hdd_try_disconnect
11779 * This function is used to disconnect from previous
11780 * connection
11781 */
11782static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
11783{
11784 long ret = 0;
11785 hdd_station_ctx_t *pHddStaCtx;
11786 eMib_dot11DesiredBssType connectedBssType;
11787
11788 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11789
11790 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
11791
11792 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
11793 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
11794 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
11795 {
11796 /* Issue disconnect to CSR */
11797 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11798 if( eHAL_STATUS_SUCCESS ==
11799 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11800 pAdapter->sessionId,
11801 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11802 {
11803 ret = wait_for_completion_interruptible_timeout(
11804 &pAdapter->disconnect_comp_var,
11805 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11806 if (0 >= ret)
11807 {
11808 hddLog(LOGE, FL("Failed to receive disconnect event"));
11809 return -EALREADY;
11810 }
11811 }
11812 }
11813 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
11814 {
11815 ret = wait_for_completion_interruptible_timeout(
11816 &pAdapter->disconnect_comp_var,
11817 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11818 if (0 >= ret)
11819 {
11820 hddLog(LOGE, FL("Failed to receive disconnect event"));
11821 return -EALREADY;
11822 }
11823 }
11824
11825 return 0;
11826}
11827
11828/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053011829 * FUNCTION: __wlan_hdd_cfg80211_connect
11830 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011831 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011832static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011833 struct net_device *ndev,
11834 struct cfg80211_connect_params *req
11835 )
11836{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011837 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011838 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011839 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053011840 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011841
11842 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011843
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011844 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11845 TRACE_CODE_HDD_CFG80211_CONNECT,
11846 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011847 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011848 "%s: device_mode = %s (%d)", __func__,
11849 hdd_device_modetoString(pAdapter->device_mode),
11850 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011851
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011852 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011853 if (!pHddCtx)
11854 {
11855 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11856 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011857 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011858 }
11859
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011860 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011861 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011862 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011863 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011864 }
11865
Agarwal Ashish51325b52014-06-16 16:50:49 +053011866 if (vos_max_concurrent_connections_reached()) {
11867 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11868 return -ECONNREFUSED;
11869 }
11870
Jeff Johnson295189b2012-06-20 16:38:30 -070011871#ifdef WLAN_BTAMP_FEATURE
11872 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011873 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070011874 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011875 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011876 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011877 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070011878 }
11879#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011880
11881 //If Device Mode is Station Concurrent Sessions Exit BMps
11882 //P2P Mode will be taken care in Open/close adapter
11883 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011884 (vos_concurrent_open_sessions_running())) {
11885 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
11886 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011887 }
11888
11889 /*Try disconnecting if already in connected state*/
11890 status = wlan_hdd_try_disconnect(pAdapter);
11891 if ( 0 > status)
11892 {
11893 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11894 " connection"));
11895 return -EALREADY;
11896 }
11897
Jeff Johnson295189b2012-06-20 16:38:30 -070011898 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011899 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070011900
11901 if ( 0 > status)
11902 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011903 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070011904 __func__);
11905 return status;
11906 }
Mohit Khanna765234a2012-09-11 15:08:35 -070011907 if ( req->channel )
11908 {
11909 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
11910 req->ssid_len, req->bssid,
11911 req->channel->hw_value);
11912 }
11913 else
11914 {
11915 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011916 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070011917 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011918
11919 if (0 > status)
11920 {
11921 //ReEnable BMPS if disabled
11922 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
11923 (NULL != pHddCtx))
11924 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011925 if (pHddCtx->hdd_wlan_suspended)
11926 {
11927 hdd_set_pwrparams(pHddCtx);
11928 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011929 //ReEnable Bmps and Imps back
11930 hdd_enable_bmps_imps(pHddCtx);
11931 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011932 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011933 return status;
11934 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011935 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011936 EXIT();
11937 return status;
11938}
11939
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011940static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
11941 struct net_device *ndev,
11942 struct cfg80211_connect_params *req)
11943{
11944 int ret;
11945 vos_ssr_protect(__func__);
11946 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
11947 vos_ssr_unprotect(__func__);
11948
11949 return ret;
11950}
Jeff Johnson295189b2012-06-20 16:38:30 -070011951
11952/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011953 * FUNCTION: wlan_hdd_disconnect
11954 * This function is used to issue a disconnect request to SME
11955 */
11956int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
11957{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011958 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011959 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011960 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011961 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011962
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011963 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011964
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011965 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011966 if (0 != status)
11967 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011968 return status;
11969 }
11970
11971 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011972
Agarwal Ashish47d18112014-08-04 19:55:07 +053011973 /* Need to apply spin lock before decreasing active sessions
11974 * as there can be chance for double decrement if context switch
11975 * Calls hdd_DisConnectHandler.
11976 */
11977
11978 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011979 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11980 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011981 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11982 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053011983 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
11984 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011985
Abhishek Singhf4669da2014-05-26 15:07:49 +053011986 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053011987 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
11988
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011989 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011990
Mihir Shete182a0b22014-08-18 16:08:48 +053011991 /*
11992 * stop tx queues before deleting STA/BSS context from the firmware.
11993 * tx has to be disabled because the firmware can get busy dropping
11994 * the tx frames after BSS/STA has been deleted and will not send
11995 * back a response resulting in WDI timeout
11996 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053011997 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053011998 netif_tx_disable(pAdapter->dev);
11999 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012000
Mihir Shete182a0b22014-08-18 16:08:48 +053012001 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012002 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12003 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012004 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
12005 {
12006 hddLog(VOS_TRACE_LEVEL_INFO,
12007 FL("status = %d, already disconnected"),
12008 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012009
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012010 }
12011 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012012 {
12013 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012014 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012015 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012016 result = -EINVAL;
12017 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012018 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012019 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012020 &pAdapter->disconnect_comp_var,
12021 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012022 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012023 {
12024 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012025 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012026 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012027 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012028 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012029 {
12030 hddLog(VOS_TRACE_LEVEL_ERROR,
12031 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012032 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012033 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012034disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12036 FL("Set HDD connState to eConnectionState_NotConnected"));
12037 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
12038
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012039 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012040 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012041}
12042
12043
12044/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012045 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070012046 * This function is used to issue a disconnect request to SME
12047 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012048static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012049 struct net_device *dev,
12050 u16 reason
12051 )
12052{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012053 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012054 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012055 tCsrRoamProfile *pRoamProfile;
12056 hdd_station_ctx_t *pHddStaCtx;
12057 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012058#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012059 tANI_U8 staIdx;
12060#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012061
Jeff Johnson295189b2012-06-20 16:38:30 -070012062 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012063
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012064 if (!pAdapter) {
12065 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
12066 return -EINVAL;
12067 }
12068
12069 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12070 if (!pHddStaCtx) {
12071 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
12072 return -EINVAL;
12073 }
12074
12075 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12076 status = wlan_hdd_validate_context(pHddCtx);
12077 if (0 != status)
12078 {
12079 return status;
12080 }
12081
12082 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
12083
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012084 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12085 TRACE_CODE_HDD_CFG80211_DISCONNECT,
12086 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012087 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
12088 __func__, hdd_device_modetoString(pAdapter->device_mode),
12089 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012090
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012091 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
12092 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070012093
Jeff Johnson295189b2012-06-20 16:38:30 -070012094 if (NULL != pRoamProfile)
12095 {
12096 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012097 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
12098 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070012099 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012100 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070012101 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012102 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012103 switch(reason)
12104 {
12105 case WLAN_REASON_MIC_FAILURE:
12106 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
12107 break;
12108
12109 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
12110 case WLAN_REASON_DISASSOC_AP_BUSY:
12111 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
12112 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
12113 break;
12114
12115 case WLAN_REASON_PREV_AUTH_NOT_VALID:
12116 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053012117 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070012118 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
12119 break;
12120
Jeff Johnson295189b2012-06-20 16:38:30 -070012121 default:
12122 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
12123 break;
12124 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012125 pScanInfo = &pHddCtx->scan_info;
12126 if (pScanInfo->mScanPending)
12127 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012128 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012129 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012130 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012131 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012132 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012133
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012134#ifdef FEATURE_WLAN_TDLS
12135 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012136 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012137 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012138 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
12139 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012140 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012141 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012142 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012144 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012145 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012146 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012147 status = sme_DeleteTdlsPeerSta(
12148 WLAN_HDD_GET_HAL_CTX(pAdapter),
12149 pAdapter->sessionId,
12150 mac);
12151 if (status != eHAL_STATUS_SUCCESS) {
12152 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
12153 return -EPERM;
12154 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012155 }
12156 }
12157#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012158 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012159 status = wlan_hdd_disconnect(pAdapter, reasonCode);
12160 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070012161 {
12162 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012163 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012164 __func__, (int)status );
12165 return -EINVAL;
12166 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012167 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012168 else
12169 {
12170 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
12171 "called while in %d state", __func__,
12172 pHddStaCtx->conn_info.connState);
12173 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012174 }
12175 else
12176 {
12177 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
12178 }
12179
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012180 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012181 return status;
12182}
12183
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012184static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
12185 struct net_device *dev,
12186 u16 reason
12187 )
12188{
12189 int ret;
12190 vos_ssr_protect(__func__);
12191 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
12192 vos_ssr_unprotect(__func__);
12193
12194 return ret;
12195}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012196
Jeff Johnson295189b2012-06-20 16:38:30 -070012197/*
12198 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012199 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012200 * settings in IBSS mode.
12201 */
12202static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012203 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012204 struct cfg80211_ibss_params *params
12205 )
12206{
12207 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012208 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012209 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12210 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012211
Jeff Johnson295189b2012-06-20 16:38:30 -070012212 ENTER();
12213
12214 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070012215 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070012216
12217 if (params->ie_len && ( NULL != params->ie) )
12218 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012219 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12220 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012221 {
12222 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12223 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12224 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012225 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012226 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012227 tDot11fIEWPA dot11WPAIE;
12228 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012229 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012230
Wilson Yang00256342013-10-10 23:13:38 -070012231 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012232 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12233 params->ie_len, DOT11F_EID_WPA);
12234 if ( NULL != ie )
12235 {
12236 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12237 // Unpack the WPA IE
12238 //Skip past the EID byte and length byte - and four byte WiFi OUI
12239 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
12240 &ie[2+4],
12241 ie[1] - 4,
12242 &dot11WPAIE);
12243 /*Extract the multicast cipher, the encType for unicast
12244 cipher for wpa-none is none*/
12245 encryptionType =
12246 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
12247 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012248 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012249
Jeff Johnson295189b2012-06-20 16:38:30 -070012250 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
12251
12252 if (0 > status)
12253 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012254 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012255 __func__);
12256 return status;
12257 }
12258 }
12259
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012260 pWextState->roamProfile.AuthType.authType[0] =
12261 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012262 eCSR_AUTH_TYPE_OPEN_SYSTEM;
12263
12264 if (params->privacy)
12265 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012266 /* Security enabled IBSS, At this time there is no information available
12267 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070012268 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012269 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070012270 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012271 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070012272 *enable privacy bit in beacons */
12273
12274 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12275 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012276 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
12277 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070012278 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12279 pWextState->roamProfile.EncryptionType.numEntries = 1;
12280 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070012281 return status;
12282}
12283
12284/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012285 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012286 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012287 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012288static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012289 struct net_device *dev,
12290 struct cfg80211_ibss_params *params
12291 )
12292{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012293 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012294 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12295 tCsrRoamProfile *pRoamProfile;
12296 int status;
krunal sonie9002db2013-11-25 14:24:17 -080012297 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012298 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12299 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012300
12301 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012302
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012303 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12304 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
12305 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012306 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012307 "%s: device_mode = %s (%d)", __func__,
12308 hdd_device_modetoString(pAdapter->device_mode),
12309 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012310
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012311 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012312 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012313 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012314 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012315 }
12316
12317 if (NULL == pWextState)
12318 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012319 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012320 __func__);
12321 return -EIO;
12322 }
12323
Agarwal Ashish51325b52014-06-16 16:50:49 +053012324 if (vos_max_concurrent_connections_reached()) {
12325 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12326 return -ECONNREFUSED;
12327 }
12328
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012329 /*Try disconnecting if already in connected state*/
12330 status = wlan_hdd_try_disconnect(pAdapter);
12331 if ( 0 > status)
12332 {
12333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12334 " IBSS connection"));
12335 return -EALREADY;
12336 }
12337
Jeff Johnson295189b2012-06-20 16:38:30 -070012338 pRoamProfile = &pWextState->roamProfile;
12339
12340 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
12341 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012342 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012343 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012344 return -EINVAL;
12345 }
12346
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012347 /* BSSID is provided by upper layers hence no need to AUTO generate */
12348 if (NULL != params->bssid) {
12349 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12350 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
12351 hddLog (VOS_TRACE_LEVEL_ERROR,
12352 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12353 return -EIO;
12354 }
12355 }
krunal sonie9002db2013-11-25 14:24:17 -080012356 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
12357 {
12358 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12359 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
12360 {
12361 hddLog (VOS_TRACE_LEVEL_ERROR,
12362 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12363 return -EIO;
12364 }
12365 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
12366 if (!params->bssid)
12367 {
12368 hddLog (VOS_TRACE_LEVEL_ERROR,
12369 "%s:Failed memory allocation", __func__);
12370 return -EIO;
12371 }
12372 vos_mem_copy((v_U8_t *)params->bssid,
12373 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
12374 VOS_MAC_ADDR_SIZE);
12375 alloc_bssid = VOS_TRUE;
12376 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012377
Jeff Johnson295189b2012-06-20 16:38:30 -070012378 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070012379 if (NULL !=
12380#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12381 params->chandef.chan)
12382#else
12383 params->channel)
12384#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012385 {
12386 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012387 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12388 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
12389 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12390 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012391
12392 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012393 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070012394 ieee80211_frequency_to_channel(
12395#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12396 params->chandef.chan->center_freq);
12397#else
12398 params->channel->center_freq);
12399#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012400
12401 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12402 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070012403 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012404 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
12405 __func__);
12406 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012407 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012408
12409 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012410 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012411 if (channelNum == validChan[indx])
12412 {
12413 break;
12414 }
12415 }
12416 if (indx >= numChans)
12417 {
12418 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012419 __func__, channelNum);
12420 return -EINVAL;
12421 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012422 /* Set the Operational Channel */
12423 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
12424 channelNum);
12425 pRoamProfile->ChannelInfo.numOfChannels = 1;
12426 pHddStaCtx->conn_info.operationChannel = channelNum;
12427 pRoamProfile->ChannelInfo.ChannelList =
12428 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070012429 }
12430
12431 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012432 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070012433 if (status < 0)
12434 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012435 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070012436 __func__);
12437 return status;
12438 }
12439
12440 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012441 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012442 params->ssid_len, params->bssid,
12443 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012444
12445 if (0 > status)
12446 {
12447 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
12448 return status;
12449 }
12450
krunal sonie9002db2013-11-25 14:24:17 -080012451 if (NULL != params->bssid &&
12452 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
12453 alloc_bssid == VOS_TRUE)
12454 {
12455 vos_mem_free(params->bssid);
12456 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012457 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012458 return 0;
12459}
12460
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012461static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
12462 struct net_device *dev,
12463 struct cfg80211_ibss_params *params
12464 )
12465{
12466 int ret = 0;
12467
12468 vos_ssr_protect(__func__);
12469 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
12470 vos_ssr_unprotect(__func__);
12471
12472 return ret;
12473}
12474
Jeff Johnson295189b2012-06-20 16:38:30 -070012475/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012476 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012477 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012478 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012479static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012480 struct net_device *dev
12481 )
12482{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012483 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012484 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12485 tCsrRoamProfile *pRoamProfile;
12486 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012487 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012488
12489 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012490
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012491 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12492 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
12493 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012494 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012495 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012496 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012497 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012498 }
12499
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012500 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
12501 hdd_device_modetoString(pAdapter->device_mode),
12502 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012503 if (NULL == pWextState)
12504 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012505 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012506 __func__);
12507 return -EIO;
12508 }
12509
12510 pRoamProfile = &pWextState->roamProfile;
12511
12512 /* Issue disconnect only if interface type is set to IBSS */
12513 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
12514 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012515 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012516 __func__);
12517 return -EINVAL;
12518 }
12519
12520 /* Issue Disconnect request */
12521 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12522 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12523 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12524
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012525 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012526 return 0;
12527}
12528
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012529static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12530 struct net_device *dev
12531 )
12532{
12533 int ret = 0;
12534
12535 vos_ssr_protect(__func__);
12536 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12537 vos_ssr_unprotect(__func__);
12538
12539 return ret;
12540}
12541
Jeff Johnson295189b2012-06-20 16:38:30 -070012542/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012543 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012544 * This function is used to set the phy parameters
12545 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12546 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012547static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012548 u32 changed)
12549{
12550 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12551 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012552 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012553
12554 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012555
12556 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012557 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
12558 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012559
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012560 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012561 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012562 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012563 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012564 }
12565
Jeff Johnson295189b2012-06-20 16:38:30 -070012566 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
12567 {
12568 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
12569 WNI_CFG_RTS_THRESHOLD_STAMAX :
12570 wiphy->rts_threshold;
12571
12572 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012573 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070012574 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012575 hddLog(VOS_TRACE_LEVEL_ERROR,
12576 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012577 __func__, rts_threshold);
12578 return -EINVAL;
12579 }
12580
12581 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
12582 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012583 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012584 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012585 hddLog(VOS_TRACE_LEVEL_ERROR,
12586 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012587 __func__, rts_threshold);
12588 return -EIO;
12589 }
12590
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012591 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012592 rts_threshold);
12593 }
12594
12595 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
12596 {
12597 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
12598 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
12599 wiphy->frag_threshold;
12600
12601 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012602 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012603 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012604 hddLog(VOS_TRACE_LEVEL_ERROR,
12605 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012606 frag_threshold);
12607 return -EINVAL;
12608 }
12609
12610 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
12611 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012612 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012613 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012614 hddLog(VOS_TRACE_LEVEL_ERROR,
12615 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012616 __func__, frag_threshold);
12617 return -EIO;
12618 }
12619
12620 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
12621 frag_threshold);
12622 }
12623
12624 if ((changed & WIPHY_PARAM_RETRY_SHORT)
12625 || (changed & WIPHY_PARAM_RETRY_LONG))
12626 {
12627 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
12628 wiphy->retry_short :
12629 wiphy->retry_long;
12630
12631 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
12632 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
12633 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012634 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012635 __func__, retry_value);
12636 return -EINVAL;
12637 }
12638
12639 if (changed & WIPHY_PARAM_RETRY_SHORT)
12640 {
12641 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
12642 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012643 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012644 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012645 hddLog(VOS_TRACE_LEVEL_ERROR,
12646 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012647 __func__, retry_value);
12648 return -EIO;
12649 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012650 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012651 __func__, retry_value);
12652 }
12653 else if (changed & WIPHY_PARAM_RETRY_SHORT)
12654 {
12655 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
12656 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012657 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012658 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012659 hddLog(VOS_TRACE_LEVEL_ERROR,
12660 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012661 __func__, retry_value);
12662 return -EIO;
12663 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012664 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012665 __func__, retry_value);
12666 }
12667 }
12668
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012669 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012670 return 0;
12671}
12672
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012673static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
12674 u32 changed)
12675{
12676 int ret;
12677
12678 vos_ssr_protect(__func__);
12679 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
12680 vos_ssr_unprotect(__func__);
12681
12682 return ret;
12683}
12684
Jeff Johnson295189b2012-06-20 16:38:30 -070012685/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012686 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012687 * This function is used to set the txpower
12688 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012689static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012690#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12691 struct wireless_dev *wdev,
12692#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012693#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012694 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012695#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012696 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012697#endif
12698 int dbm)
12699{
12700 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012701 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012702 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12703 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012704 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012705
12706 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012707
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012708 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12709 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
12710 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012711 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012712 if (0 != status)
12713 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012714 return status;
12715 }
12716
12717 hHal = pHddCtx->hHal;
12718
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012719 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
12720 dbm, ccmCfgSetCallback,
12721 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012722 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012723 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012724 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
12725 return -EIO;
12726 }
12727
12728 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
12729 dbm);
12730
12731 switch(type)
12732 {
12733 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
12734 /* Fall through */
12735 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
12736 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
12737 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012738 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
12739 __func__);
12740 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012741 }
12742 break;
12743 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012744 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012745 __func__);
12746 return -EOPNOTSUPP;
12747 break;
12748 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012749 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
12750 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070012751 return -EIO;
12752 }
12753
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012754 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012755 return 0;
12756}
12757
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012758static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
12759#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12760 struct wireless_dev *wdev,
12761#endif
12762#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12763 enum tx_power_setting type,
12764#else
12765 enum nl80211_tx_power_setting type,
12766#endif
12767 int dbm)
12768{
12769 int ret;
12770 vos_ssr_protect(__func__);
12771 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
12772#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12773 wdev,
12774#endif
12775#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12776 type,
12777#else
12778 type,
12779#endif
12780 dbm);
12781 vos_ssr_unprotect(__func__);
12782
12783 return ret;
12784}
12785
Jeff Johnson295189b2012-06-20 16:38:30 -070012786/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012787 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012788 * This function is used to read the txpower
12789 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012790static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012791#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12792 struct wireless_dev *wdev,
12793#endif
12794 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070012795{
12796
12797 hdd_adapter_t *pAdapter;
12798 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012799 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012800
Jeff Johnsone7245742012-09-05 17:12:55 -070012801 ENTER();
12802
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012803 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012804 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012805 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012806 *dbm = 0;
12807 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012808 }
12809
Jeff Johnson295189b2012-06-20 16:38:30 -070012810 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
12811 if (NULL == pAdapter)
12812 {
12813 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
12814 return -ENOENT;
12815 }
12816
12817 wlan_hdd_get_classAstats(pAdapter);
12818 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
12819
Jeff Johnsone7245742012-09-05 17:12:55 -070012820 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012821 return 0;
12822}
12823
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012824static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
12825#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12826 struct wireless_dev *wdev,
12827#endif
12828 int *dbm)
12829{
12830 int ret;
12831
12832 vos_ssr_protect(__func__);
12833 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
12834#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12835 wdev,
12836#endif
12837 dbm);
12838 vos_ssr_unprotect(__func__);
12839
12840 return ret;
12841}
12842
12843
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012844static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070012845 u8* mac, struct station_info *sinfo)
12846{
12847 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12848 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12849 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053012850 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070012851
12852 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
12853 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012854
12855 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
12856 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
12857 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
12858 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
12859 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
12860 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
12861 tANI_U16 maxRate = 0;
12862 tANI_U16 myRate;
12863 tANI_U16 currentRate = 0;
12864 tANI_U8 maxSpeedMCS = 0;
12865 tANI_U8 maxMCSIdx = 0;
12866 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053012867 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012868 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012869 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012870
Leo Chang6f8870f2013-03-26 18:11:36 -070012871#ifdef WLAN_FEATURE_11AC
12872 tANI_U32 vht_mcs_map;
12873 eDataRate11ACMaxMcs vhtMaxMcs;
12874#endif /* WLAN_FEATURE_11AC */
12875
Jeff Johnsone7245742012-09-05 17:12:55 -070012876 ENTER();
12877
Jeff Johnson295189b2012-06-20 16:38:30 -070012878 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
12879 (0 == ssidlen))
12880 {
12881 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
12882 " Invalid ssidlen, %d", __func__, ssidlen);
12883 /*To keep GUI happy*/
12884 return 0;
12885 }
12886
Mukul Sharma811205f2014-07-09 21:07:30 +053012887 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
12888 {
12889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12890 "%s: Roaming in progress, so unable to proceed this request", __func__);
12891 return 0;
12892 }
12893
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012894 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012895 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012896 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012897 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012898 }
12899
Jeff Johnson295189b2012-06-20 16:38:30 -070012900
Kiet Lam3b17fc82013-09-27 05:24:08 +053012901 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
12902 sinfo->filled |= STATION_INFO_SIGNAL;
12903
c_hpothu09f19542014-05-30 21:53:31 +053012904 wlan_hdd_get_station_stats(pAdapter);
12905 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
12906
12907 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053012908 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
12909 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053012910 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053012911 {
12912 rate_flags = pAdapter->maxRateFlags;
12913 }
c_hpothu44ff4e02014-05-08 00:13:57 +053012914
Jeff Johnson295189b2012-06-20 16:38:30 -070012915 //convert to the UI units of 100kbps
12916 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
12917
12918#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070012919 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 -070012920 sinfo->signal,
12921 pCfg->reportMaxLinkSpeed,
12922 myRate,
12923 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012924 (int) pCfg->linkSpeedRssiMid,
12925 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070012926 (int) rate_flags,
12927 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012928#endif //LINKSPEED_DEBUG_ENABLED
12929
12930 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
12931 {
12932 // we do not want to necessarily report the current speed
12933 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
12934 {
12935 // report the max possible speed
12936 rssidx = 0;
12937 }
12938 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
12939 {
12940 // report the max possible speed with RSSI scaling
12941 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
12942 {
12943 // report the max possible speed
12944 rssidx = 0;
12945 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012946 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070012947 {
12948 // report middle speed
12949 rssidx = 1;
12950 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012951 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
12952 {
12953 // report middle speed
12954 rssidx = 2;
12955 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012956 else
12957 {
12958 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012959 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070012960 }
12961 }
12962 else
12963 {
12964 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
12965 hddLog(VOS_TRACE_LEVEL_ERROR,
12966 "%s: Invalid value for reportMaxLinkSpeed: %u",
12967 __func__, pCfg->reportMaxLinkSpeed);
12968 rssidx = 0;
12969 }
12970
12971 maxRate = 0;
12972
12973 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012974 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
12975 OperationalRates, &ORLeng))
12976 {
12977 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12978 /*To keep GUI happy*/
12979 return 0;
12980 }
12981
Jeff Johnson295189b2012-06-20 16:38:30 -070012982 for (i = 0; i < ORLeng; i++)
12983 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012984 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012985 {
12986 /* Validate Rate Set */
12987 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
12988 {
12989 currentRate = supported_data_rate[j].supported_rate[rssidx];
12990 break;
12991 }
12992 }
12993 /* Update MAX rate */
12994 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12995 }
12996
12997 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012998 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
12999 ExtendedRates, &ERLeng))
13000 {
13001 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13002 /*To keep GUI happy*/
13003 return 0;
13004 }
13005
Jeff Johnson295189b2012-06-20 16:38:30 -070013006 for (i = 0; i < ERLeng; i++)
13007 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013008 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013009 {
13010 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
13011 {
13012 currentRate = supported_data_rate[j].supported_rate[rssidx];
13013 break;
13014 }
13015 }
13016 /* Update MAX rate */
13017 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13018 }
c_hpothu79aab322014-07-14 21:11:01 +053013019
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013020 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053013021 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013022 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053013023 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070013024 {
c_hpothu79aab322014-07-14 21:11:01 +053013025 if (rate_flags & eHAL_TX_RATE_VHT80)
13026 mode = 2;
13027 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
13028 mode = 1;
13029 else
13030 mode = 0;
13031
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013032 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
13033 MCSRates, &MCSLeng))
13034 {
13035 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13036 /*To keep GUI happy*/
13037 return 0;
13038 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013039 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070013040#ifdef WLAN_FEATURE_11AC
13041 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013042 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070013043 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013044 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013045 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070013046 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070013047 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013048 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013049 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013050 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070013051 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013052 maxMCSIdx = 7;
13053 }
13054 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
13055 {
13056 maxMCSIdx = 8;
13057 }
13058 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
13059 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013060 //VHT20 is supporting 0~8
13061 if (rate_flags & eHAL_TX_RATE_VHT20)
13062 maxMCSIdx = 8;
13063 else
13064 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070013065 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013066
c_hpothu79aab322014-07-14 21:11:01 +053013067 if (0 != rssidx)/*check for scaled */
13068 {
13069 //get middle rate MCS index if rssi=1/2
13070 for (i=0; i <= maxMCSIdx; i++)
13071 {
13072 if (sinfo->signal <= rssiMcsTbl[mode][i])
13073 {
13074 maxMCSIdx = i;
13075 break;
13076 }
13077 }
13078 }
13079
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013080 if (rate_flags & eHAL_TX_RATE_VHT80)
13081 {
13082 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
13083 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
13084 }
13085 else if (rate_flags & eHAL_TX_RATE_VHT40)
13086 {
13087 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
13088 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
13089 }
13090 else if (rate_flags & eHAL_TX_RATE_VHT20)
13091 {
13092 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
13093 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
13094 }
13095
Leo Chang6f8870f2013-03-26 18:11:36 -070013096 maxSpeedMCS = 1;
13097 if (currentRate > maxRate)
13098 {
13099 maxRate = currentRate;
13100 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013101
Leo Chang6f8870f2013-03-26 18:11:36 -070013102 }
13103 else
13104#endif /* WLAN_FEATURE_11AC */
13105 {
13106 if (rate_flags & eHAL_TX_RATE_HT40)
13107 {
13108 rateFlag |= 1;
13109 }
13110 if (rate_flags & eHAL_TX_RATE_SGI)
13111 {
13112 rateFlag |= 2;
13113 }
13114
Girish Gowli01abcee2014-07-31 20:18:55 +053013115 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053013116 if (rssidx == 1 || rssidx == 2)
13117 {
13118 //get middle rate MCS index if rssi=1/2
13119 for (i=0; i <= 7; i++)
13120 {
13121 if (sinfo->signal <= rssiMcsTbl[mode][i])
13122 {
13123 temp = i+1;
13124 break;
13125 }
13126 }
13127 }
c_hpothu79aab322014-07-14 21:11:01 +053013128
13129 for (i = 0; i < MCSLeng; i++)
13130 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013131 for (j = 0; j < temp; j++)
13132 {
13133 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
13134 {
13135 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
13136 break;
13137 }
13138 }
13139 if ((j < temp) && (currentRate > maxRate))
13140 {
13141 maxRate = currentRate;
13142 maxSpeedMCS = 1;
13143 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
13144 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013145 }
13146 }
13147 }
13148
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013149 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
13150 {
13151 maxRate = myRate;
13152 maxSpeedMCS = 1;
13153 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13154 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013155 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053013156 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070013157 {
13158 maxRate = myRate;
13159 if (rate_flags & eHAL_TX_RATE_LEGACY)
13160 {
13161 maxSpeedMCS = 0;
13162 }
13163 else
13164 {
13165 maxSpeedMCS = 1;
13166 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13167 }
13168 }
13169
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013170 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070013171 {
13172 sinfo->txrate.legacy = maxRate;
13173#ifdef LINKSPEED_DEBUG_ENABLED
13174 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
13175#endif //LINKSPEED_DEBUG_ENABLED
13176 }
13177 else
13178 {
13179 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070013180#ifdef WLAN_FEATURE_11AC
13181 sinfo->txrate.nss = 1;
13182 if (rate_flags & eHAL_TX_RATE_VHT80)
13183 {
13184 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013185 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070013186 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013187 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070013188 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013189 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13190 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13191 }
13192 else if (rate_flags & eHAL_TX_RATE_VHT20)
13193 {
13194 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13195 }
13196#endif /* WLAN_FEATURE_11AC */
13197 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
13198 {
13199 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13200 if (rate_flags & eHAL_TX_RATE_HT40)
13201 {
13202 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13203 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013204 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013205 if (rate_flags & eHAL_TX_RATE_SGI)
13206 {
13207 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13208 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013209
Jeff Johnson295189b2012-06-20 16:38:30 -070013210#ifdef LINKSPEED_DEBUG_ENABLED
13211 pr_info("Reporting MCS rate %d flags %x\n",
13212 sinfo->txrate.mcs,
13213 sinfo->txrate.flags );
13214#endif //LINKSPEED_DEBUG_ENABLED
13215 }
13216 }
13217 else
13218 {
13219 // report current rate instead of max rate
13220
13221 if (rate_flags & eHAL_TX_RATE_LEGACY)
13222 {
13223 //provide to the UI in units of 100kbps
13224 sinfo->txrate.legacy = myRate;
13225#ifdef LINKSPEED_DEBUG_ENABLED
13226 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
13227#endif //LINKSPEED_DEBUG_ENABLED
13228 }
13229 else
13230 {
13231 //must be MCS
13232 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013233#ifdef WLAN_FEATURE_11AC
13234 sinfo->txrate.nss = 1;
13235 if (rate_flags & eHAL_TX_RATE_VHT80)
13236 {
13237 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13238 }
13239 else
13240#endif /* WLAN_FEATURE_11AC */
13241 {
13242 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13243 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013244 if (rate_flags & eHAL_TX_RATE_SGI)
13245 {
13246 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13247 }
13248 if (rate_flags & eHAL_TX_RATE_HT40)
13249 {
13250 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13251 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013252#ifdef WLAN_FEATURE_11AC
13253 else if (rate_flags & eHAL_TX_RATE_VHT80)
13254 {
13255 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
13256 }
13257#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070013258#ifdef LINKSPEED_DEBUG_ENABLED
13259 pr_info("Reporting actual MCS rate %d flags %x\n",
13260 sinfo->txrate.mcs,
13261 sinfo->txrate.flags );
13262#endif //LINKSPEED_DEBUG_ENABLED
13263 }
13264 }
13265 sinfo->filled |= STATION_INFO_TX_BITRATE;
13266
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013267 sinfo->tx_packets =
13268 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
13269 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
13270 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
13271 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
13272
13273 sinfo->tx_retries =
13274 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
13275 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
13276 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
13277 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
13278
13279 sinfo->tx_failed =
13280 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
13281 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
13282 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
13283 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
13284
13285 sinfo->filled |=
13286 STATION_INFO_TX_PACKETS |
13287 STATION_INFO_TX_RETRIES |
13288 STATION_INFO_TX_FAILED;
13289
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013290 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13291 TRACE_CODE_HDD_CFG80211_GET_STA,
13292 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013293 EXIT();
13294 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013295}
13296
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013297static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13298 u8* mac, struct station_info *sinfo)
13299{
13300 int ret;
13301
13302 vos_ssr_protect(__func__);
13303 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
13304 vos_ssr_unprotect(__func__);
13305
13306 return ret;
13307}
13308
13309static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070013310 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070013311{
13312 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013313 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013314 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013315 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013316
Jeff Johnsone7245742012-09-05 17:12:55 -070013317 ENTER();
13318
Jeff Johnson295189b2012-06-20 16:38:30 -070013319 if (NULL == pAdapter)
13320 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013321 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013322 return -ENODEV;
13323 }
13324
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013325 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13326 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
13327 pAdapter->sessionId, timeout));
13328
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013329 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013330 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013331 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013332 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013333 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013334 }
13335
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013336 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
13337 (TRUE == pHddCtx->hdd_wlan_suspended) &&
13338 (pHddCtx->cfg_ini->fhostArpOffload) &&
13339 (eConnectionState_Associated ==
13340 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13341 {
Amar Singhald53568e2013-09-26 11:03:45 -070013342
13343 hddLog(VOS_TRACE_LEVEL_INFO,
13344 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053013345 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013346 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13347 {
13348 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013349 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013350 __func__, vos_status);
13351 }
13352 }
13353
Jeff Johnson295189b2012-06-20 16:38:30 -070013354 /**The get power cmd from the supplicant gets updated by the nl only
13355 *on successful execution of the function call
13356 *we are oppositely mapped w.r.t mode in the driver
13357 **/
13358 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
13359
13360 if (VOS_STATUS_E_FAILURE == vos_status)
13361 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13363 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013364 return -EINVAL;
13365 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013366 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013367 return 0;
13368}
13369
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013370static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
13371 struct net_device *dev, bool mode, int timeout)
13372{
13373 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013374
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013375 vos_ssr_protect(__func__);
13376 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
13377 vos_ssr_unprotect(__func__);
13378
13379 return ret;
13380}
Jeff Johnson295189b2012-06-20 16:38:30 -070013381#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013382static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
13383 struct net_device *netdev,
13384 u8 key_index)
13385{
13386 ENTER();
13387 return 0;
13388}
13389
Jeff Johnson295189b2012-06-20 16:38:30 -070013390static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013391 struct net_device *netdev,
13392 u8 key_index)
13393{
13394 int ret;
13395 vos_ssr_protect(__func__);
13396 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
13397 vos_ssr_unprotect(__func__);
13398 return ret;
13399}
13400#endif //LINUX_VERSION_CODE
13401
13402#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13403static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13404 struct net_device *dev,
13405 struct ieee80211_txq_params *params)
13406{
13407 ENTER();
13408 return 0;
13409}
13410#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13411static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13412 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013413{
Jeff Johnsone7245742012-09-05 17:12:55 -070013414 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013415 return 0;
13416}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013417#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070013418
13419#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13420static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013421 struct net_device *dev,
13422 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013423{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013424 int ret;
13425
13426 vos_ssr_protect(__func__);
13427 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
13428 vos_ssr_unprotect(__func__);
13429 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013430}
13431#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13432static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
13433 struct ieee80211_txq_params *params)
13434{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013435 int ret;
13436
13437 vos_ssr_protect(__func__);
13438 ret = __wlan_hdd_set_txq_params(wiphy, params);
13439 vos_ssr_unprotect(__func__);
13440 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013441}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013442#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013443
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013444static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013445 struct net_device *dev,
13446 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070013447{
13448 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013449 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013450 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013451 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013452 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013453 v_CONTEXT_t pVosContext = NULL;
13454 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013455
Jeff Johnsone7245742012-09-05 17:12:55 -070013456 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013457
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013458 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070013459 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013460 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013461 return -EINVAL;
13462 }
13463
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013464 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13465 TRACE_CODE_HDD_CFG80211_DEL_STA,
13466 pAdapter->sessionId, pAdapter->device_mode));
13467
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013468 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13469 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013470 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013471 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013472 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013473 }
13474
Jeff Johnson295189b2012-06-20 16:38:30 -070013475 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013476 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013477 )
13478 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013479 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13480 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13481 if(pSapCtx == NULL){
13482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13483 FL("psapCtx is NULL"));
13484 return -ENOENT;
13485 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013486 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013487 {
13488 v_U16_t i;
13489 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13490 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013491 if ((pSapCtx->aStaInfo[i].isUsed) &&
13492 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070013493 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013494 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013495 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013496 ETHER_ADDR_LEN);
13497
Jeff Johnson295189b2012-06-20 16:38:30 -070013498 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013499 "%s: Delete STA with MAC::"
13500 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013501 __func__,
13502 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
13503 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013504 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013505 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013506 }
13507 }
13508 }
13509 else
13510 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013511
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013512 vos_status = hdd_softap_GetStaId(pAdapter,
13513 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013514 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13515 {
13516 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013517 "%s: Skip this DEL STA as this is not used::"
13518 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013519 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013520 return -ENOENT;
13521 }
13522
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013523 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013524 {
13525 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013526 "%s: Skip this DEL STA as deauth is in progress::"
13527 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013528 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013529 return -ENOENT;
13530 }
13531
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013532 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013533
Jeff Johnson295189b2012-06-20 16:38:30 -070013534 hddLog(VOS_TRACE_LEVEL_INFO,
13535 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013536 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013537 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013538 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013539
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013540 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013541 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13542 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013543 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013544 hddLog(VOS_TRACE_LEVEL_INFO,
13545 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013546 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013547 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013548 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013549 return -ENOENT;
13550 }
13551
Jeff Johnson295189b2012-06-20 16:38:30 -070013552 }
13553 }
13554
13555 EXIT();
13556
13557 return 0;
13558}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013559
13560#ifdef CFG80211_DEL_STA_V2
13561static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13562 struct net_device *dev,
13563 struct station_del_parameters *param)
13564#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013565static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13566 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013567#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013568{
13569 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013570 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070013571
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013572 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013573
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013574#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013575 if (NULL == param) {
13576 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013577 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013578 return -EINVAL;
13579 }
13580
13581 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
13582 param->subtype, &delStaParams);
13583
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013584#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053013585 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013586 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013587#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013588 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
13589
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013590 vos_ssr_unprotect(__func__);
13591
13592 return ret;
13593}
13594
13595static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013596 struct net_device *dev, u8 *mac, struct station_parameters *params)
13597{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013598 hdd_adapter_t *pAdapter;
13599 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013600 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013601#ifdef FEATURE_WLAN_TDLS
13602 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013603
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013604 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013605
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013606 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13607 if (NULL == pAdapter)
13608 {
13609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13610 "%s: Adapter is NULL",__func__);
13611 return -EINVAL;
13612 }
13613 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13614 status = wlan_hdd_validate_context(pHddCtx);
13615 if (0 != status)
13616 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013617 return status;
13618 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013619
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013620 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13621 TRACE_CODE_HDD_CFG80211_ADD_STA,
13622 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013623 mask = params->sta_flags_mask;
13624
13625 set = params->sta_flags_set;
13626
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053013627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013628 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
13629 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013630
13631 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13632 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013633 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013634 }
13635 }
13636#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013637 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013638 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013639}
13640
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013641static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
13642 struct net_device *dev, u8 *mac, struct station_parameters *params)
13643{
13644 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013645
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013646 vos_ssr_protect(__func__);
13647 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
13648 vos_ssr_unprotect(__func__);
13649
13650 return ret;
13651}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013652#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070013653
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013654static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070013655 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013656{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013657 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13658 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013659 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013660 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013661 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013662 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070013663
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013664 ENTER();
13665
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013666 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013667 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013668 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013669 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013670 return -EINVAL;
13671 }
13672
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013673 if (!pmksa) {
13674 hddLog(LOGE, FL("pmksa is NULL"));
13675 return -EINVAL;
13676 }
13677
13678 if (!pmksa->bssid || !pmksa->pmkid) {
13679 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
13680 pmksa->bssid, pmksa->pmkid);
13681 return -EINVAL;
13682 }
13683
13684 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
13685 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13686
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013687 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13688 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013689 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013690 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013691 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013692 }
13693
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013694 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013695 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13696
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013697 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
13698 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013699
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013700 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013701 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013702 &pmk_id, 1, FALSE);
13703
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013704 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13705 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
13706 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013707
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013708 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013709 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013710}
13711
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013712static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
13713 struct cfg80211_pmksa *pmksa)
13714{
13715 int ret;
13716
13717 vos_ssr_protect(__func__);
13718 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
13719 vos_ssr_unprotect(__func__);
13720
13721 return ret;
13722}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013723
Wilson Yang6507c4e2013-10-01 20:11:19 -070013724
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013725static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070013726 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013727{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013728 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13729 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013730 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013731 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013732
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013733 ENTER();
13734
Wilson Yang6507c4e2013-10-01 20:11:19 -070013735 /* Validate pAdapter */
13736 if (NULL == pAdapter)
13737 {
13738 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
13739 return -EINVAL;
13740 }
13741
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013742 if (!pmksa) {
13743 hddLog(LOGE, FL("pmksa is NULL"));
13744 return -EINVAL;
13745 }
13746
13747 if (!pmksa->bssid) {
13748 hddLog(LOGE, FL("pmksa->bssid is NULL"));
13749 return -EINVAL;
13750 }
13751
Kiet Lam98c46a12014-10-31 15:34:57 -070013752 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
13753 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13754
Wilson Yang6507c4e2013-10-01 20:11:19 -070013755 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13756 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070013757 if (0 != status)
13758 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070013759 return status;
13760 }
13761
13762 /*Retrieve halHandle*/
13763 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13764
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013765 /* Delete the PMKID CSR cache */
13766 if (eHAL_STATUS_SUCCESS !=
13767 sme_RoamDelPMKIDfromCache(halHandle,
13768 pAdapter->sessionId, pmksa->bssid, FALSE)) {
13769 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
13770 MAC_ADDR_ARRAY(pmksa->bssid));
13771 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013772 }
13773
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013774 EXIT();
13775 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013776}
13777
Wilson Yang6507c4e2013-10-01 20:11:19 -070013778
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013779static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
13780 struct cfg80211_pmksa *pmksa)
13781{
13782 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013783
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013784 vos_ssr_protect(__func__);
13785 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
13786 vos_ssr_unprotect(__func__);
13787
13788 return ret;
13789
13790}
13791
13792static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013793{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013794 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13795 tHalHandle halHandle;
13796 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013797 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013798
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013799 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070013800
13801 /* Validate pAdapter */
13802 if (NULL == pAdapter)
13803 {
13804 hddLog(VOS_TRACE_LEVEL_ERROR,
13805 "%s: Invalid Adapter" ,__func__);
13806 return -EINVAL;
13807 }
13808
13809 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13810 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070013811 if (0 != status)
13812 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070013813 return status;
13814 }
13815
13816 /*Retrieve halHandle*/
13817 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13818
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013819 /* Flush the PMKID cache in CSR */
13820 if (eHAL_STATUS_SUCCESS !=
13821 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
13822 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
13823 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013824 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013825 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080013826 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013827}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013828
13829static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
13830{
13831 int ret;
13832
13833 vos_ssr_protect(__func__);
13834 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
13835 vos_ssr_unprotect(__func__);
13836
13837 return ret;
13838}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013839#endif
13840
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013841#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013842static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13843 struct net_device *dev,
13844 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013845{
13846 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13847 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013848 hdd_context_t *pHddCtx;
13849 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013850
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013851 ENTER();
13852
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013853 if (NULL == pAdapter)
13854 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013855 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013856 return -ENODEV;
13857 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013858 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13859 ret = wlan_hdd_validate_context(pHddCtx);
13860 if (0 != ret)
13861 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013862 return ret;
13863 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013864 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013865 if (NULL == pHddStaCtx)
13866 {
13867 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
13868 return -EINVAL;
13869 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013870
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013871 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13872 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
13873 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013874 // Added for debug on reception of Re-assoc Req.
13875 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
13876 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013877 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013878 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080013879 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013880 }
13881
13882#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080013883 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013884 ftie->ie_len);
13885#endif
13886
13887 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013888 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13889 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013890 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013891
13892 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013893 return 0;
13894}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013895
13896static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13897 struct net_device *dev,
13898 struct cfg80211_update_ft_ies_params *ftie)
13899{
13900 int ret;
13901
13902 vos_ssr_protect(__func__);
13903 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
13904 vos_ssr_unprotect(__func__);
13905
13906 return ret;
13907}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013908#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013909
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013910#ifdef FEATURE_WLAN_SCAN_PNO
13911
13912void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
13913 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
13914{
13915 int ret;
13916 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
13917 hdd_context_t *pHddCtx;
13918
Nirav Shah80830bf2013-12-31 16:35:12 +053013919 ENTER();
13920
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013921 if (NULL == pAdapter)
13922 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013923 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013924 "%s: HDD adapter is Null", __func__);
13925 return ;
13926 }
13927
13928 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13929 if (NULL == pHddCtx)
13930 {
13931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13932 "%s: HDD context is Null!!!", __func__);
13933 return ;
13934 }
13935
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013936 spin_lock(&pHddCtx->schedScan_lock);
13937 if (TRUE == pHddCtx->isWiphySuspended)
13938 {
13939 pHddCtx->isSchedScanUpdatePending = TRUE;
13940 spin_unlock(&pHddCtx->schedScan_lock);
13941 hddLog(VOS_TRACE_LEVEL_INFO,
13942 "%s: Update cfg80211 scan database after it resume", __func__);
13943 return ;
13944 }
13945 spin_unlock(&pHddCtx->schedScan_lock);
13946
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013947 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
13948
13949 if (0 > ret)
13950 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
13951
13952 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13954 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013955}
13956
13957/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013958 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013959 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013960 */
13961static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
13962{
13963 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13964 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013965 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013966 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13967 int status = 0;
13968 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13969
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013970 /* The current firmware design does not allow PNO during any
13971 * active sessions. Hence, determine the active sessions
13972 * and return a failure.
13973 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013974 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
13975 {
13976 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013977 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013978
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013979 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
13980 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
13981 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
13982 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
13983 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053013984 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013985 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013986 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013987 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013988 }
13989 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13990 pAdapterNode = pNext;
13991 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013992 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013993}
13994
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013995void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
13996{
13997 hdd_adapter_t *pAdapter = callbackContext;
13998 hdd_context_t *pHddCtx;
13999
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014000 ENTER();
14001
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014002 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
14003 {
14004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14005 FL("Invalid adapter or adapter has invalid magic"));
14006 return;
14007 }
14008
14009 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14010 if (0 != wlan_hdd_validate_context(pHddCtx))
14011 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014012 return;
14013 }
14014
c_hpothub53c45d2014-08-18 16:53:14 +053014015 if (VOS_STATUS_SUCCESS != status)
14016 {
14017 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014018 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053014019 pHddCtx->isPnoEnable = FALSE;
14020 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014021
14022 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
14023 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014024 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014025}
14026
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014027/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014028 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
14029 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014030 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014031static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014032 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14033{
14034 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014035 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014036 hdd_context_t *pHddCtx;
14037 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014038 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053014039 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
14040 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014041 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14042 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014043 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014044 hdd_config_t *pConfig = NULL;
14045 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014046
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014047 ENTER();
14048
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014049 if (NULL == pAdapter)
14050 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014052 "%s: HDD adapter is Null", __func__);
14053 return -ENODEV;
14054 }
14055
14056 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014057 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014058
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014059 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014060 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014061 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014062 }
14063
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014064 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014065 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14066 if (NULL == hHal)
14067 {
14068 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14069 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014070 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014071 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053014072 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014073 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053014074 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014075 {
14076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14077 "%s: aborting the existing scan is unsuccessfull", __func__);
14078 return -EBUSY;
14079 }
14080
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014081 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014082 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014084 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014085 return -EBUSY;
14086 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014087
c_hpothu37f21312014-04-09 21:49:54 +053014088 if (TRUE == pHddCtx->isPnoEnable)
14089 {
14090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14091 FL("already PNO is enabled"));
14092 return -EBUSY;
14093 }
c_hpothu225aa7c2014-10-22 17:45:13 +053014094
14095 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
14096 {
14097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14098 "%s: abort ROC failed ", __func__);
14099 return -EBUSY;
14100 }
14101
c_hpothu37f21312014-04-09 21:49:54 +053014102 pHddCtx->isPnoEnable = TRUE;
14103
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014104 pnoRequest.enable = 1; /*Enable PNO */
14105 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014106
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014107 if (( !pnoRequest.ucNetworksCount ) ||
14108 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014109 {
14110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014111 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014112 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014113 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014114 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014115 goto error;
14116 }
14117
14118 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
14119 {
14120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014121 "%s: Incorrect number of channels %d",
14122 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014123 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014124 goto error;
14125 }
14126
14127 /* Framework provides one set of channels(all)
14128 * common for all saved profile */
14129 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14130 channels_allowed, &num_channels_allowed))
14131 {
14132 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14133 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014134 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014135 goto error;
14136 }
14137 /* Checking each channel against allowed channel list */
14138 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053014139 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014140 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014141 char chList [(request->n_channels*5)+1];
14142 int len;
14143 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014144 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014145 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014146 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014147 if (request->channels[i]->hw_value == channels_allowed[indx])
14148 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014149 if ((!pConfig->enableDFSPnoChnlScan) &&
14150 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
14151 {
14152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14153 "%s : Dropping DFS channel : %d",
14154 __func__,channels_allowed[indx]);
14155 num_ignore_dfs_ch++;
14156 break;
14157 }
14158
Nirav Shah80830bf2013-12-31 16:35:12 +053014159 valid_ch[num_ch++] = request->channels[i]->hw_value;
14160 len += snprintf(chList+len, 5, "%d ",
14161 request->channels[i]->hw_value);
14162 break ;
14163 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014164 }
14165 }
Nirav Shah80830bf2013-12-31 16:35:12 +053014166 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014167
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014168 /*If all channels are DFS and dropped, then ignore the PNO request*/
14169 if (num_ignore_dfs_ch == request->n_channels)
14170 {
14171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14172 "%s : All requested channels are DFS channels", __func__);
14173 ret = -EINVAL;
14174 goto error;
14175 }
14176 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014177
14178 pnoRequest.aNetworks =
14179 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14180 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014181 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014182 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14183 FL("failed to allocate memory aNetworks %u"),
14184 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14185 goto error;
14186 }
14187 vos_mem_zero(pnoRequest.aNetworks,
14188 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14189
14190 /* Filling per profile params */
14191 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
14192 {
14193 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014194 request->match_sets[i].ssid.ssid_len;
14195
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014196 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
14197 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014198 {
14199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014200 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014201 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014202 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014203 goto error;
14204 }
14205
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014206 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014207 request->match_sets[i].ssid.ssid,
14208 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14210 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014211 i, pnoRequest.aNetworks[i].ssId.ssId);
14212 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
14213 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
14214 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014215
14216 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014217 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
14218 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014219
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014220 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014221 }
14222
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014223 for (i = 0; i < request->n_ssids; i++)
14224 {
14225 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014226 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014227 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014228 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014229 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014230 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014231 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014232 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014233 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014234 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014235 break;
14236 }
14237 j++;
14238 }
14239 }
14240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14241 "Number of hidden networks being Configured = %d",
14242 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080014244 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014245
14246 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14247 if (pnoRequest.p24GProbeTemplate == NULL)
14248 {
14249 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14250 FL("failed to allocate memory p24GProbeTemplate %u"),
14251 SIR_PNO_MAX_PB_REQ_SIZE);
14252 goto error;
14253 }
14254
14255 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14256 if (pnoRequest.p5GProbeTemplate == NULL)
14257 {
14258 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14259 FL("failed to allocate memory p5GProbeTemplate %u"),
14260 SIR_PNO_MAX_PB_REQ_SIZE);
14261 goto error;
14262 }
14263
14264 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14265 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14266
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053014267 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
14268 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014269 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014270 pnoRequest.us24GProbeTemplateLen = request->ie_len;
14271 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
14272 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014273
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014274 pnoRequest.us5GProbeTemplateLen = request->ie_len;
14275 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
14276 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014277 }
14278
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014279 /* Driver gets only one time interval which is hardcoded in
14280 * supplicant for 10000ms. Taking power consumption into account 6 timers
14281 * will be used, Timervalue is increased exponentially i.e 10,20,40,
14282 * 80,160,320 secs. And number of scan cycle for each timer
14283 * is configurable through INI param gPNOScanTimerRepeatValue.
14284 * If it is set to 0 only one timer will be used and PNO scan cycle
14285 * will be repeated after each interval specified by supplicant
14286 * till PNO is disabled.
14287 */
14288 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014289 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014290 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014291 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014292 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
14293
14294 tempInterval = (request->interval)/1000;
14295 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14296 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
14297 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014298 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014299 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014300 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014301 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014302 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014303 tempInterval *= 2;
14304 }
14305 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014306 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014307
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014308 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014309
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014310 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014311 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
14312 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014313 pAdapter->pno_req_status = 0;
14314
Nirav Shah80830bf2013-12-31 16:35:12 +053014315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14316 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014317 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
14318 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053014319
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014320 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014321 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014322 hdd_cfg80211_sched_scan_done_callback, pAdapter);
14323 if (eHAL_STATUS_SUCCESS != status)
14324 {
14325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014326 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014327 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014328 goto error;
14329 }
14330
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014331 ret = wait_for_completion_timeout(
14332 &pAdapter->pno_comp_var,
14333 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
14334 if (0 >= ret)
14335 {
14336 // Did not receive the response for PNO enable in time.
14337 // Assuming the PNO enable was success.
14338 // Returning error from here, because we timeout, results
14339 // in side effect of Wifi (Wifi Setting) not to work.
14340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14341 FL("Timed out waiting for PNO to be Enabled"));
14342 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014343 }
14344
14345 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053014346 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014347
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014348error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14350 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053014351 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014352 if (pnoRequest.aNetworks)
14353 vos_mem_free(pnoRequest.aNetworks);
14354 if (pnoRequest.p24GProbeTemplate)
14355 vos_mem_free(pnoRequest.p24GProbeTemplate);
14356 if (pnoRequest.p5GProbeTemplate)
14357 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014358
14359 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014360 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014361}
14362
14363/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014364 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
14365 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014366 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014367static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
14368 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14369{
14370 int ret;
14371
14372 vos_ssr_protect(__func__);
14373 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
14374 vos_ssr_unprotect(__func__);
14375
14376 return ret;
14377}
14378
14379/*
14380 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
14381 * Function to disable PNO
14382 */
14383static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014384 struct net_device *dev)
14385{
14386 eHalStatus status = eHAL_STATUS_FAILURE;
14387 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14388 hdd_context_t *pHddCtx;
14389 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014390 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014391 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014392
14393 ENTER();
14394
14395 if (NULL == pAdapter)
14396 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014398 "%s: HDD adapter is Null", __func__);
14399 return -ENODEV;
14400 }
14401
14402 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014403
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014404 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014405 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014407 "%s: HDD context is Null", __func__);
14408 return -ENODEV;
14409 }
14410
14411 /* The return 0 is intentional when isLogpInProgress and
14412 * isLoadUnloadInProgress. We did observe a crash due to a return of
14413 * failure in sched_scan_stop , especially for a case where the unload
14414 * of the happens at the same time. The function __cfg80211_stop_sched_scan
14415 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
14416 * success. If it returns a failure , then its next invocation due to the
14417 * clean up of the second interface will have the dev pointer corresponding
14418 * to the first one leading to a crash.
14419 */
14420 if (pHddCtx->isLogpInProgress)
14421 {
14422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14423 "%s: LOGP in Progress. Ignore!!!", __func__);
14424 return ret;
14425 }
14426
Mihir Shete18156292014-03-11 15:38:30 +053014427 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014428 {
14429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14430 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14431 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014432 }
14433
14434 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14435 if (NULL == hHal)
14436 {
14437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14438 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014439 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014440 }
14441
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014442 pnoRequest.enable = 0; /* Disable PNO */
14443 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014444
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014445 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014446 pAdapter->sessionId,
14447 NULL, pAdapter);
14448 if (eHAL_STATUS_SUCCESS != status)
14449 {
14450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14451 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014452 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014453 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014454 }
c_hpothu37f21312014-04-09 21:49:54 +053014455 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014456
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014457error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014458 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014459 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014460
14461 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014462 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014463}
14464
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014465/*
14466 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
14467 * NL interface to disable PNO
14468 */
14469static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
14470 struct net_device *dev)
14471{
14472 int ret;
14473
14474 vos_ssr_protect(__func__);
14475 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
14476 vos_ssr_unprotect(__func__);
14477
14478 return ret;
14479}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014480#endif /*FEATURE_WLAN_SCAN_PNO*/
14481
14482
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014483#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014484#if TDLS_MGMT_VERSION2
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014485static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014486 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014487 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
14488#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014489static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014490 u8 *peer, u8 action_code, u8 dialog_token,
14491 u16 status_code, const u8 *buf, size_t len)
14492#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014493{
14494
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014495 hdd_adapter_t *pAdapter;
14496 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014497 u8 peerMac[6];
14498 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070014499 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080014500 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070014501 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014502 int ret;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014503#if !(TDLS_MGMT_VERSION2)
14504 u32 peer_capability = 0;
14505#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014506 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014507
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014508 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14509 if (NULL == pAdapter)
14510 {
14511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14512 "%s: Adapter is NULL",__func__);
14513 return -EINVAL;
14514 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014515 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14516 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
14517 pAdapter->sessionId, action_code));
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014518 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014519 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014520 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014522 "Invalid arguments");
14523 return -EINVAL;
14524 }
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014525 if (pHddCtx->isLogpInProgress)
14526 {
14527 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14528 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053014529 wlan_hdd_tdls_set_link_status(pAdapter,
14530 peer,
14531 eTDLS_LINK_IDLE,
14532 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014533 return -EBUSY;
14534 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014535 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
14536 {
14537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14538 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14539 return -EAGAIN;
14540 }
Hoonki Lee27511902013-03-14 18:19:06 -070014541 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014542 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070014544 "%s: TDLS mode is disabled OR not enabled in FW."
14545 MAC_ADDRESS_STR " action %d declined.",
14546 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014547 return -ENOTSUPP;
14548 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014549
Hoonki Lee27511902013-03-14 18:19:06 -070014550 /* other than teardown frame, other mgmt frames are not sent if disabled */
14551 if (SIR_MAC_TDLS_TEARDOWN != action_code)
14552 {
14553 /* if tdls_mode is disabled to respond to peer's request */
14554 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
14555 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070014557 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014558 " TDLS mode is disabled. action %d declined.",
14559 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070014560
14561 return -ENOTSUPP;
14562 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014563
14564 if (vos_max_concurrent_connections_reached())
14565 {
14566 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14567 return -EINVAL;
14568 }
Hoonki Lee27511902013-03-14 18:19:06 -070014569 }
14570
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014571 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
14572 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014573 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014574 {
14575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014576 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014577 " TDLS setup is ongoing. action %d declined.",
14578 __func__, MAC_ADDR_ARRAY(peer), action_code);
14579 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014580 }
14581 }
14582
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014583 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
14584 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080014585 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014586 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14587 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014588 {
14589 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
14590 we return error code at 'add_station()'. Hence we have this
14591 check again in addtion to add_station().
14592 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014593 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014594 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14596 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014597 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
14598 __func__, MAC_ADDR_ARRAY(peer), action_code,
14599 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053014600 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080014601 }
14602 else
14603 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014604 /* maximum reached. tweak to send error code to peer and return
14605 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014606 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14608 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014609 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
14610 __func__, MAC_ADDR_ARRAY(peer), status_code,
14611 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070014612 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014613 /* fall through to send setup resp with failure status
14614 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014615 }
14616 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014617 else
14618 {
14619 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014620 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014621 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014622 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014624 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
14625 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014626 return -EPERM;
14627 }
14628 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014629 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014630 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014631
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014632 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014633 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014634 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
14635 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014636
Hoonki Leea34dd892013-02-05 22:56:02 -080014637 /*Except teardown responder will not be used so just make 0*/
14638 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014639 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080014640 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014641
14642 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014643 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014644
14645 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
14646 responder = pTdlsPeer->is_responder;
14647 else
Hoonki Leea34dd892013-02-05 22:56:02 -080014648 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014650 "%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 -070014651 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
14652 dialog_token, status_code, len);
14653 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080014654 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014655 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014656
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014657 /* For explicit trigger of DIS_REQ come out of BMPS for
14658 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070014659 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014660 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
14661 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070014662 {
14663 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
14664 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014666 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014667 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
14668 if (status != VOS_STATUS_SUCCESS) {
14669 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
14670 }
Hoonki Lee14621352013-04-16 17:51:19 -070014671 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014672 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
14673 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED)) {
14674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
14675 }
14676 }
Hoonki Lee14621352013-04-16 17:51:19 -070014677 }
14678
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014679 /* make sure doesn't call send_mgmt() while it is pending */
14680 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
14681 {
14682 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014683 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014684 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014685 ret = -EBUSY;
14686 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014687 }
14688
14689 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014690 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
14691
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014692 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053014693 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014694
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014695 if (VOS_STATUS_SUCCESS != status)
14696 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14698 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014699 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014700 ret = -EINVAL;
14701 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014702 }
14703
Hoonki Leed37cbb32013-04-20 00:31:14 -070014704 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
14705 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
14706
14707 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014708 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070014709 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014710 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070014711 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014712 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080014713
14714 if (pHddCtx->isLogpInProgress)
14715 {
14716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14717 "%s: LOGP in Progress. Ignore!!!", __func__);
14718 return -EAGAIN;
14719 }
14720
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014721 ret = -EINVAL;
14722 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014723 }
14724
Gopichand Nakkala05922802013-03-14 12:23:19 -070014725 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070014726 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014727 ret = max_sta_failed;
14728 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070014729 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014730
Hoonki Leea34dd892013-02-05 22:56:02 -080014731 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
14732 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014733 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE)) {
14734 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
14735 }
Hoonki Leea34dd892013-02-05 22:56:02 -080014736 }
14737 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
14738 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014739 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE)) {
14740 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
14741 }
Hoonki Leea34dd892013-02-05 22:56:02 -080014742 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014743
14744 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014745
14746tx_failed:
14747 /* add_station will be called before sending TDLS_SETUP_REQ and
14748 * TDLS_SETUP_RSP and as part of add_station driver will enable
14749 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
14750 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
14751 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
14752 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
14753 */
14754
14755 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
14756 (SIR_MAC_TDLS_SETUP_RSP == action_code))
14757 wlan_hdd_tdls_check_bmps(pAdapter);
14758 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014759}
14760
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014761#if TDLS_MGMT_VERSION2
14762static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14763 u8 *peer, u8 action_code, u8 dialog_token,
14764 u16 status_code, u32 peer_capability,
14765 const u8 *buf, size_t len)
14766#else
14767static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14768 u8 *peer, u8 action_code, u8 dialog_token,
14769 u16 status_code, const u8 *buf, size_t len)
14770#endif
14771{
14772 int ret;
14773
14774 vos_ssr_protect(__func__);
14775#if TDLS_MGMT_VERSION2
14776 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14777 status_code, peer_capability, buf, len);
14778#else
14779 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14780 status_code, buf, len);
14781#endif
14782 vos_ssr_unprotect(__func__);
14783
14784 return ret;
14785}
Atul Mittal115287b2014-07-08 13:26:33 +053014786
14787int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
14788 u8 *peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014789 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053014790 cfg80211_exttdls_callback callback)
14791{
14792
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014793 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053014794 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014795 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053014796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14797 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
14798 __func__, MAC_ADDR_ARRAY(peer));
14799
14800 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14801 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14802
14803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014804 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
14805 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
14806 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053014807 return -ENOTSUPP;
14808 }
14809
14810 /* To cater the requirement of establishing the TDLS link
14811 * irrespective of the data traffic , get an entry of TDLS peer.
14812 */
14813 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
14814 if (pTdlsPeer == NULL) {
14815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14816 "%s: peer " MAC_ADDRESS_STR " not existing",
14817 __func__, MAC_ADDR_ARRAY(peer));
14818 return -EINVAL;
14819 }
14820
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053014821 /* check FW TDLS Off Channel capability */
14822 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
14823 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014824 {
14825 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
14826 pTdlsPeer->peerParams.global_operating_class =
14827 tdls_peer_params->global_operating_class;
14828 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
14829 pTdlsPeer->peerParams.min_bandwidth_kbps =
14830 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014831 /* check configured channel is valid, non dfs and
14832 * not current operating channel */
14833 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
14834 tdls_peer_params->channel)) &&
14835 (pHddStaCtx) &&
14836 (tdls_peer_params->channel !=
14837 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014838 {
14839 pTdlsPeer->isOffChannelConfigured = TRUE;
14840 }
14841 else
14842 {
14843 pTdlsPeer->isOffChannelConfigured = FALSE;
14844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14845 "%s: Configured Tdls Off Channel is not valid", __func__);
14846
14847 }
14848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014849 "%s: tdls_off_channel %d isOffChannelConfigured %d "
14850 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014851 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014852 pTdlsPeer->isOffChannelConfigured,
14853 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014854 }
14855 else
14856 {
14857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053014858 "%s: TDLS off channel FW capability %d or "
14859 "Invalid TDLS Peer Params", __func__,
14860 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014861 }
14862
Atul Mittal115287b2014-07-08 13:26:33 +053014863 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
14864
14865 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14866 " %s TDLS Add Force Peer Failed",
14867 __func__);
14868 return -EINVAL;
14869 }
14870 /*EXT TDLS*/
14871
14872 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
14873 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14874 " %s TDLS set callback Failed",
14875 __func__);
14876 return -EINVAL;
14877 }
14878
14879 return(0);
14880
14881}
14882
14883int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
14884{
14885
14886 hddTdlsPeer_t *pTdlsPeer;
14887 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14888 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14889 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
14890 __func__, MAC_ADDR_ARRAY(peer));
14891
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014892 if (0 != wlan_hdd_validate_context(pHddCtx)) {
14893 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
14894 return -EINVAL;
14895 }
14896
Atul Mittal115287b2014-07-08 13:26:33 +053014897 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14898 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14899
14900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014901 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
14902 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
14903 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053014904 return -ENOTSUPP;
14905 }
14906
14907
14908 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14909
14910 if ( NULL == pTdlsPeer ) {
14911 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
14912 " peer not exsting",
14913 __func__, MAC_ADDR_ARRAY(peer));
14914 return -EINVAL;
14915 }
14916 else {
14917 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
14918 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014919 /* if channel switch is configured, reset
14920 the channel for this peer */
14921 if (TRUE == pTdlsPeer->isOffChannelConfigured)
14922 {
14923 pTdlsPeer->peerParams.channel = 0;
14924 pTdlsPeer->isOffChannelConfigured = FALSE;
14925 }
Atul Mittal115287b2014-07-08 13:26:33 +053014926 }
14927
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014928 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
14929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053014930 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014931 }
Atul Mittal115287b2014-07-08 13:26:33 +053014932
14933 /*EXT TDLS*/
14934
14935 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
14936
14937 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14938 " %s TDLS set callback Failed",
14939 __func__);
14940 return -EINVAL;
14941 }
14942 return(0);
14943
14944}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014945static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014946 u8 *peer, enum nl80211_tdls_operation oper)
14947{
14948 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14949 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014950 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014951 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014952
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014953 ENTER();
14954
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014955 if (!pAdapter) {
14956 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
14957 return -EINVAL;
14958 }
14959
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014960 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14961 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
14962 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014963 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014964 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014965 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014966 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014967 return -EINVAL;
14968 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014969
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014970 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014971 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014972 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014973 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014974 }
14975
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014976
14977 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014978 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014979 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014980 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014981 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
14982 "Cannot process TDLS commands",
14983 pHddCtx->cfg_ini->fEnableTDLSSupport,
14984 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014985 return -ENOTSUPP;
14986 }
14987
14988 switch (oper) {
14989 case NL80211_TDLS_ENABLE_LINK:
14990 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014991 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014992 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014993 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053014994 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014995 tANI_U16 numCurrTdlsPeers = 0;
14996 hddTdlsPeer_t *connPeer = NULL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014997
Sunil Dutt41de4e22013-11-14 18:09:02 +053014998 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053014999 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015000 if ( NULL == pTdlsPeer ) {
15001 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15002 " (oper %d) not exsting. ignored",
15003 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15004 return -EINVAL;
15005 }
15006
15007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15008 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15009 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15010 "NL80211_TDLS_ENABLE_LINK");
15011
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070015012 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
15013 {
15014 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
15015 MAC_ADDRESS_STR " failed",
15016 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
15017 return -EINVAL;
15018 }
15019
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015020 /* TDLS Off Channel, Disable tdls channel switch,
15021 when there are more than one tdls link */
15022 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15023 if (numCurrTdlsPeers == 1)
15024 {
15025 /* get connected peer and send disable tdls off chan */
15026 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
15027 if (connPeer && (connPeer->isOffChannelConfigured == TRUE))
15028 {
15029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15030 "%s: More then one peer connected, Disable "
15031 "TDLS channel switch", __func__);
15032
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015033 ret = sme_SendTdlsChanSwitchReq(
15034 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015035 pAdapter->sessionId,
15036 connPeer->peerMac,
15037 connPeer->peerParams.channel,
15038 TDLS_OFF_CHANNEL_BW_OFFSET,
15039 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015040 if (ret != VOS_STATUS_SUCCESS) {
15041 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel request"));
15042 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015043 }
15044 else
15045 {
15046 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15047 "%s: No TDLS Connected Peer or "
15048 "isOffChannelConfigured %d",
15049 __func__,
15050 (connPeer ? connPeer->isOffChannelConfigured : -1));
15051 }
15052 }
15053
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015054 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015055 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015056 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053015057
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015058 if (0 != wlan_hdd_tdls_get_link_establish_params(
15059 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015061 return -EINVAL;
15062 }
15063 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015064
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015065 ret = sme_SendTdlsLinkEstablishParams(
15066 WLAN_HDD_GET_HAL_CTX(pAdapter),
15067 pAdapter->sessionId, peer,
15068 &tdlsLinkEstablishParams);
15069 if (ret != VOS_STATUS_SUCCESS) {
15070 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
15071 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015072 /* Send TDLS peer UAPSD capabilities to the firmware and
15073 * register with the TL on after the response for this operation
15074 * is received .
15075 */
15076 ret = wait_for_completion_interruptible_timeout(
15077 &pAdapter->tdls_link_establish_req_comp,
15078 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
15079 if (ret <= 0)
15080 {
15081 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15082 "%s: Link Establish Request Faled Status %ld",
15083 __func__, ret);
15084 return -EINVAL;
15085 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015086 }
Atul Mittal115287b2014-07-08 13:26:33 +053015087 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15088 eTDLS_LINK_CONNECTED,
15089 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015090 staDesc.ucSTAId = pTdlsPeer->staId;
15091 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015092 ret = WLANTL_UpdateTdlsSTAClient(
15093 pHddCtx->pvosContext,
15094 &staDesc);
15095 if (ret != VOS_STATUS_SUCCESS) {
15096 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
15097 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053015098
Gopichand Nakkala471708b2013-06-04 20:03:01 +053015099 /* Mark TDLS client Authenticated .*/
15100 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
15101 pTdlsPeer->staId,
15102 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015103 if (VOS_STATUS_SUCCESS == status)
15104 {
Hoonki Lee14621352013-04-16 17:51:19 -070015105 if (pTdlsPeer->is_responder == 0)
15106 {
15107 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
15108
15109 wlan_hdd_tdls_timer_restart(pAdapter,
15110 &pTdlsPeer->initiatorWaitTimeoutTimer,
15111 WAIT_TIME_TDLS_INITIATOR);
15112 /* suspend initiator TX until it receives direct packet from the
15113 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015114 ret = WLANTL_SuspendDataTx(
15115 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15116 &staId, NULL);
15117 if (ret != VOS_STATUS_SUCCESS) {
15118 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
15119 }
Hoonki Lee14621352013-04-16 17:51:19 -070015120 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015121 wlan_hdd_tdls_increment_peer_count(pAdapter);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015122
15123 /* TDLS Off Channel, Enable tdls channel switch,
15124 when their is only one tdls link and it supports */
15125 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15126 if ((numCurrTdlsPeers == 1) &&
15127 (TRUE == pTdlsPeer->isOffChannelSupported) &&
15128 (TRUE == pTdlsPeer->isOffChannelConfigured))
15129 {
15130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15131 "%s: Send TDLS channel switch request for channel %d",
15132 __func__, pTdlsPeer->peerParams.channel);
15133 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
15134 pAdapter->sessionId,
15135 pTdlsPeer->peerMac,
15136 pTdlsPeer->peerParams.channel,
15137 TDLS_OFF_CHANNEL_BW_OFFSET,
15138 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015139 if (ret != VOS_STATUS_SUCCESS) {
15140 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
15141 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015142 }
15143 else
15144 {
15145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15146 "%s: TDLS channel switch request not sent"
15147 " numCurrTdlsPeers %d "
15148 "isOffChannelSupported %d "
15149 "isOffChannelConfigured %d",
15150 __func__, numCurrTdlsPeers,
15151 pTdlsPeer->isOffChannelSupported,
15152 pTdlsPeer->isOffChannelConfigured);
15153 }
15154
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015155 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015156 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015157
15158 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015159 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
15160 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015161 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015162 int ac;
15163 uint8 ucAc[4] = { WLANTL_AC_VO,
15164 WLANTL_AC_VI,
15165 WLANTL_AC_BK,
15166 WLANTL_AC_BE };
15167 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
15168 for(ac=0; ac < 4; ac++)
15169 {
15170 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15171 pTdlsPeer->staId, ucAc[ac],
15172 tlTid[ac], tlTid[ac], 0, 0,
15173 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015174 if (status != VOS_STATUS_SUCCESS) {
15175 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
15176 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015177 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015178 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015179 }
15180
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015181 }
15182 break;
15183 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080015184 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015185 tANI_U16 numCurrTdlsPeers = 0;
15186 hddTdlsPeer_t *connPeer = NULL;
15187
Sunil Dutt41de4e22013-11-14 18:09:02 +053015188 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15189
15190 if ( NULL == pTdlsPeer ) {
15191 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15192 " (oper %d) not exsting. ignored",
15193 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15194 return -EINVAL;
15195 }
15196
15197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15198 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15199 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15200 "NL80211_TDLS_DISABLE_LINK");
15201
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015202 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080015203 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015204 long status;
15205
Atul Mittal271a7652014-09-12 13:18:22 +053015206
15207 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15208 eTDLS_LINK_TEARING,
15209 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
15210 eTDLS_LINK_UNSPECIFIED:
15211 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015212 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
15213
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015214 status = sme_DeleteTdlsPeerSta(
15215 WLAN_HDD_GET_HAL_CTX(pAdapter),
15216 pAdapter->sessionId, peer );
15217 if (status != VOS_STATUS_SUCCESS) {
15218 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15219 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015220
15221 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
15222 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053015223 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053015224 eTDLS_LINK_IDLE,
15225 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015226 if (status <= 0)
15227 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15229 "%s: Del station failed status %ld",
15230 __func__, status);
15231 return -EPERM;
15232 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015233
15234 /* TDLS Off Channel, Enable tdls channel switch,
15235 when their is only one tdls link and it supports */
15236 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15237 if (numCurrTdlsPeers == 1)
15238 {
15239 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
15240 if ((connPeer) &&
15241 (connPeer->isOffChannelSupported == TRUE) &&
15242 (connPeer->isOffChannelConfigured == TRUE))
15243 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015244 status = sme_SendTdlsChanSwitchReq(
15245 WLAN_HDD_GET_HAL_CTX(pAdapter),
15246 pAdapter->sessionId,
15247 connPeer->peerMac,
15248 connPeer->peerParams.channel,
15249 TDLS_OFF_CHANNEL_BW_OFFSET,
15250 TDLS_CHANNEL_SWITCH_ENABLE);
15251 if (status != VOS_STATUS_SUCCESS) {
15252 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
15253 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015254 }
15255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15256 "%s: TDLS channel switch "
15257 "isOffChannelSupported %d "
15258 "isOffChannelConfigured %d",
15259 __func__,
15260 (connPeer ? connPeer->isOffChannelSupported : -1),
15261 (connPeer ? connPeer->isOffChannelConfigured : -1));
15262 }
15263 else
15264 {
15265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15266 "%s: TDLS channel switch request not sent "
15267 "numCurrTdlsPeers %d ",
15268 __func__, numCurrTdlsPeers);
15269 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015270 }
15271 else
15272 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015273 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15274 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080015275 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015276 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015277 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015278 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015279 {
Atul Mittal115287b2014-07-08 13:26:33 +053015280 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015281
Atul Mittal115287b2014-07-08 13:26:33 +053015282 if (0 != status)
15283 {
15284 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15285 "%s: Error in TDLS Teardown", __func__);
15286 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015287 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053015288 break;
15289 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015290 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015291 {
Atul Mittal115287b2014-07-08 13:26:33 +053015292 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
15293 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015294 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053015295 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015296
Atul Mittal115287b2014-07-08 13:26:33 +053015297 if (0 != status)
15298 {
15299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15300 "%s: Error in TDLS Setup", __func__);
15301 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053015302 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053015303 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015304 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015305 case NL80211_TDLS_DISCOVERY_REQ:
15306 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15308 "%s: We don't support in-driver setup/teardown/discovery "
15309 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015310 return -ENOTSUPP;
15311 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15313 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015314 return -ENOTSUPP;
15315 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015316
15317 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015318 return 0;
15319}
Chilam NG571c65a2013-01-19 12:27:36 +053015320
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015321static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
15322 u8 *peer, enum nl80211_tdls_operation oper)
15323{
15324 int ret;
15325
15326 vos_ssr_protect(__func__);
15327 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
15328 vos_ssr_unprotect(__func__);
15329
15330 return ret;
15331}
15332
Chilam NG571c65a2013-01-19 12:27:36 +053015333int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
15334 struct net_device *dev, u8 *peer)
15335{
Arif Hussaina7c8e412013-11-20 11:06:42 -080015336 hddLog(VOS_TRACE_LEVEL_INFO,
15337 "tdls send discover req: "MAC_ADDRESS_STR,
15338 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053015339
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015340#if TDLS_MGMT_VERSION2
15341 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15342 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15343#else
Chilam NG571c65a2013-01-19 12:27:36 +053015344 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15345 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015346#endif
Chilam NG571c65a2013-01-19 12:27:36 +053015347}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015348#endif
15349
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015350#ifdef WLAN_FEATURE_GTK_OFFLOAD
15351/*
15352 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
15353 * Callback rountine called upon receiving response for
15354 * get offload info
15355 */
15356void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
15357 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
15358{
15359
15360 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015361 tANI_U8 tempReplayCounter[8];
15362 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015363
15364 ENTER();
15365
15366 if (NULL == pAdapter)
15367 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053015368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015369 "%s: HDD adapter is Null", __func__);
15370 return ;
15371 }
15372
15373 if (NULL == pGtkOffloadGetInfoRsp)
15374 {
15375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15376 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
15377 return ;
15378 }
15379
15380 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
15381 {
15382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15383 "%s: wlan Failed to get replay counter value",
15384 __func__);
15385 return ;
15386 }
15387
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015388 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15389 /* Update replay counter */
15390 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
15391 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15392
15393 {
15394 /* changing from little to big endian since supplicant
15395 * works on big endian format
15396 */
15397 int i;
15398 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15399
15400 for (i = 0; i < 8; i++)
15401 {
15402 tempReplayCounter[7-i] = (tANI_U8)p[i];
15403 }
15404 }
15405
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015406 /* Update replay counter to NL */
15407 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015408 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015409}
15410
15411/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015412 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015413 * This function is used to offload GTK rekeying job to the firmware.
15414 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015415int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015416 struct cfg80211_gtk_rekey_data *data)
15417{
15418 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15419 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15420 hdd_station_ctx_t *pHddStaCtx;
15421 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015422 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015423 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015424 eHalStatus status = eHAL_STATUS_FAILURE;
15425
15426 ENTER();
15427
15428 if (NULL == pAdapter)
15429 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015431 "%s: HDD adapter is Null", __func__);
15432 return -ENODEV;
15433 }
15434
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015435 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15436 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
15437 pAdapter->sessionId, pAdapter->device_mode));
15438
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015439 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015440 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015441 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015442 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015443 }
15444
15445 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15446 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15447 if (NULL == hHal)
15448 {
15449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15450 "%s: HAL context is Null!!!", __func__);
15451 return -EAGAIN;
15452 }
15453
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015454 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
15455 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
15456 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
15457 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015458 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015459 {
15460 /* changing from big to little endian since driver
15461 * works on little endian format
15462 */
15463 tANI_U8 *p =
15464 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
15465 int i;
15466
15467 for (i = 0; i < 8; i++)
15468 {
15469 p[7-i] = data->replay_ctr[i];
15470 }
15471 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015472
15473 if (TRUE == pHddCtx->hdd_wlan_suspended)
15474 {
15475 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015476 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
15477 sizeof (tSirGtkOffloadParams));
15478 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015479 pAdapter->sessionId);
15480
15481 if (eHAL_STATUS_SUCCESS != status)
15482 {
15483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15484 "%s: sme_SetGTKOffload failed, returned %d",
15485 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053015486
15487 /* Need to clear any trace of key value in the memory.
15488 * Thus zero out the memory even though it is local
15489 * variable.
15490 */
15491 vos_mem_zero(&hddGtkOffloadReqParams,
15492 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015493 return status;
15494 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015495 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15496 "%s: sme_SetGTKOffload successfull", __func__);
15497 }
15498 else
15499 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015500 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15501 "%s: wlan not suspended GTKOffload request is stored",
15502 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015503 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015504
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053015505 /* Need to clear any trace of key value in the memory.
15506 * Thus zero out the memory even though it is local
15507 * variable.
15508 */
15509 vos_mem_zero(&hddGtkOffloadReqParams,
15510 sizeof(hddGtkOffloadReqParams));
15511
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015512 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015513 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015514}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015515
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015516int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
15517 struct cfg80211_gtk_rekey_data *data)
15518{
15519 int ret;
15520
15521 vos_ssr_protect(__func__);
15522 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
15523 vos_ssr_unprotect(__func__);
15524
15525 return ret;
15526}
15527#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015528/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015529 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015530 * This function is used to set access control policy
15531 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015532static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15533 struct net_device *dev,
15534 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015535{
15536 int i;
15537 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15538 hdd_hostapd_state_t *pHostapdState;
15539 tsap_Config_t *pConfig;
15540 v_CONTEXT_t pVosContext = NULL;
15541 hdd_context_t *pHddCtx;
15542 int status;
15543
15544 ENTER();
15545
15546 if (NULL == pAdapter)
15547 {
15548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15549 "%s: HDD adapter is Null", __func__);
15550 return -ENODEV;
15551 }
15552
15553 if (NULL == params)
15554 {
15555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15556 "%s: params is Null", __func__);
15557 return -EINVAL;
15558 }
15559
15560 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15561 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015562 if (0 != status)
15563 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015564 return status;
15565 }
15566
15567 pVosContext = pHddCtx->pvosContext;
15568 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
15569
15570 if (NULL == pHostapdState)
15571 {
15572 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15573 "%s: pHostapdState is Null", __func__);
15574 return -EINVAL;
15575 }
15576
15577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
15578 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
15579
15580 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
15581 {
15582 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
15583
15584 /* default value */
15585 pConfig->num_accept_mac = 0;
15586 pConfig->num_deny_mac = 0;
15587
15588 /**
15589 * access control policy
15590 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
15591 * listed in hostapd.deny file.
15592 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
15593 * listed in hostapd.accept file.
15594 */
15595 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
15596 {
15597 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
15598 }
15599 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
15600 {
15601 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
15602 }
15603 else
15604 {
15605 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15606 "%s:Acl Policy : %d is not supported",
15607 __func__, params->acl_policy);
15608 return -ENOTSUPP;
15609 }
15610
15611 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
15612 {
15613 pConfig->num_accept_mac = params->n_acl_entries;
15614 for (i = 0; i < params->n_acl_entries; i++)
15615 {
15616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15617 "** Add ACL MAC entry %i in WhiletList :"
15618 MAC_ADDRESS_STR, i,
15619 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
15620
15621 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
15622 sizeof(qcmacaddr));
15623 }
15624 }
15625 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
15626 {
15627 pConfig->num_deny_mac = params->n_acl_entries;
15628 for (i = 0; i < params->n_acl_entries; i++)
15629 {
15630 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15631 "** Add ACL MAC entry %i in BlackList :"
15632 MAC_ADDRESS_STR, i,
15633 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
15634
15635 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
15636 sizeof(qcmacaddr));
15637 }
15638 }
15639
15640 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
15641 {
15642 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15643 "%s: SAP Set Mac Acl fail", __func__);
15644 return -EINVAL;
15645 }
15646 }
15647 else
15648 {
15649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015650 "%s: Invalid device_mode = %s (%d)",
15651 __func__, hdd_device_modetoString(pAdapter->device_mode),
15652 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015653 return -EINVAL;
15654 }
15655
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015656 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015657 return 0;
15658}
15659
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015660static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15661 struct net_device *dev,
15662 const struct cfg80211_acl_data *params)
15663{
15664 int ret;
15665 vos_ssr_protect(__func__);
15666 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
15667 vos_ssr_unprotect(__func__);
15668
15669 return ret;
15670}
15671
Leo Chang9056f462013-08-01 19:21:11 -070015672#ifdef WLAN_NL80211_TESTMODE
15673#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070015674void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070015675(
15676 void *pAdapter,
15677 void *indCont
15678)
15679{
Leo Changd9df8aa2013-09-26 13:32:26 -070015680 tSirLPHBInd *lphbInd;
15681 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053015682 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070015683
15684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070015685 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070015686
c_hpothu73f35e62014-04-18 13:40:08 +053015687 if (pAdapter == NULL)
15688 {
15689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15690 "%s: pAdapter is NULL\n",__func__);
15691 return;
15692 }
15693
Leo Chang9056f462013-08-01 19:21:11 -070015694 if (NULL == indCont)
15695 {
15696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070015697 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070015698 return;
15699 }
15700
c_hpothu73f35e62014-04-18 13:40:08 +053015701 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070015702 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070015703 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053015704 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070015705 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070015706 GFP_ATOMIC);
15707 if (!skb)
15708 {
15709 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15710 "LPHB timeout, NL buffer alloc fail");
15711 return;
15712 }
15713
Leo Changac3ba772013-10-07 09:47:04 -070015714 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070015715 {
15716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15717 "WLAN_HDD_TM_ATTR_CMD put fail");
15718 goto nla_put_failure;
15719 }
Leo Changac3ba772013-10-07 09:47:04 -070015720 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070015721 {
15722 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15723 "WLAN_HDD_TM_ATTR_TYPE put fail");
15724 goto nla_put_failure;
15725 }
Leo Changac3ba772013-10-07 09:47:04 -070015726 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070015727 sizeof(tSirLPHBInd), lphbInd))
15728 {
15729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15730 "WLAN_HDD_TM_ATTR_DATA put fail");
15731 goto nla_put_failure;
15732 }
Leo Chang9056f462013-08-01 19:21:11 -070015733 cfg80211_testmode_event(skb, GFP_ATOMIC);
15734 return;
15735
15736nla_put_failure:
15737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15738 "NLA Put fail");
15739 kfree_skb(skb);
15740
15741 return;
15742}
15743#endif /* FEATURE_WLAN_LPHB */
15744
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015745static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070015746{
15747 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
15748 int err = 0;
15749#ifdef FEATURE_WLAN_LPHB
15750 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070015751 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015752
15753 ENTER();
15754
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015755 err = wlan_hdd_validate_context(pHddCtx);
15756 if (0 != err)
15757 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015758 return err;
15759 }
Leo Chang9056f462013-08-01 19:21:11 -070015760#endif /* FEATURE_WLAN_LPHB */
15761
15762 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
15763 if (err)
15764 {
15765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15766 "%s Testmode INV ATTR", __func__);
15767 return err;
15768 }
15769
15770 if (!tb[WLAN_HDD_TM_ATTR_CMD])
15771 {
15772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15773 "%s Testmode INV CMD", __func__);
15774 return -EINVAL;
15775 }
15776
15777 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
15778 {
15779#ifdef FEATURE_WLAN_LPHB
15780 /* Low Power Heartbeat configuration request */
15781 case WLAN_HDD_TM_CMD_WLAN_HB:
15782 {
15783 int buf_len;
15784 void *buf;
15785 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080015786 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070015787
15788 if (!tb[WLAN_HDD_TM_ATTR_DATA])
15789 {
15790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15791 "%s Testmode INV DATA", __func__);
15792 return -EINVAL;
15793 }
15794
15795 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
15796 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080015797
15798 hb_params_temp =(tSirLPHBReq *)buf;
15799 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
15800 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
15801 return -EINVAL;
15802
Leo Chang9056f462013-08-01 19:21:11 -070015803 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
15804 if (NULL == hb_params)
15805 {
15806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15807 "%s Request Buffer Alloc Fail", __func__);
15808 return -EINVAL;
15809 }
15810
15811 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070015812 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
15813 hb_params,
15814 wlan_hdd_cfg80211_lphb_ind_handler);
15815 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070015816 {
Leo Changd9df8aa2013-09-26 13:32:26 -070015817 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15818 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070015819 vos_mem_free(hb_params);
15820 }
Leo Chang9056f462013-08-01 19:21:11 -070015821 return 0;
15822 }
15823#endif /* FEATURE_WLAN_LPHB */
15824 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15826 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070015827 return -EOPNOTSUPP;
15828 }
15829
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015830 EXIT();
15831 return err;
Leo Chang9056f462013-08-01 19:21:11 -070015832}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015833
15834static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
15835{
15836 int ret;
15837
15838 vos_ssr_protect(__func__);
15839 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
15840 vos_ssr_unprotect(__func__);
15841
15842 return ret;
15843}
Leo Chang9056f462013-08-01 19:21:11 -070015844#endif /* CONFIG_NL80211_TESTMODE */
15845
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015846static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015847 struct net_device *dev,
15848 int idx, struct survey_info *survey)
15849{
15850 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15851 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053015852 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015853 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053015854 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015855 v_S7_t snr,rssi;
15856 int status, i, j, filled = 0;
15857
15858 ENTER();
15859
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015860 if (NULL == pAdapter)
15861 {
15862 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15863 "%s: HDD adapter is Null", __func__);
15864 return -ENODEV;
15865 }
15866
15867 if (NULL == wiphy)
15868 {
15869 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15870 "%s: wiphy is Null", __func__);
15871 return -ENODEV;
15872 }
15873
15874 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15875 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015876 if (0 != status)
15877 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015878 return status;
15879 }
15880
Mihir Sheted9072e02013-08-21 17:02:29 +053015881 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15882
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015883 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053015884 0 != pAdapter->survey_idx ||
15885 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015886 {
15887 /* The survey dump ops when implemented completely is expected to
15888 * return a survey of all channels and the ops is called by the
15889 * kernel with incremental values of the argument 'idx' till it
15890 * returns -ENONET. But we can only support the survey for the
15891 * operating channel for now. survey_idx is used to track
15892 * that the ops is called only once and then return -ENONET for
15893 * the next iteration
15894 */
15895 pAdapter->survey_idx = 0;
15896 return -ENONET;
15897 }
15898
15899 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15900
15901 wlan_hdd_get_snr(pAdapter, &snr);
15902 wlan_hdd_get_rssi(pAdapter, &rssi);
15903
15904 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
15905 hdd_wlan_get_freq(channel, &freq);
15906
15907
15908 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
15909 {
15910 if (NULL == wiphy->bands[i])
15911 {
15912 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
15913 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
15914 continue;
15915 }
15916
15917 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
15918 {
15919 struct ieee80211_supported_band *band = wiphy->bands[i];
15920
15921 if (band->channels[j].center_freq == (v_U16_t)freq)
15922 {
15923 survey->channel = &band->channels[j];
15924 /* The Rx BDs contain SNR values in dB for the received frames
15925 * while the supplicant expects noise. So we calculate and
15926 * return the value of noise (dBm)
15927 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
15928 */
15929 survey->noise = rssi - snr;
15930 survey->filled = SURVEY_INFO_NOISE_DBM;
15931 filled = 1;
15932 }
15933 }
15934 }
15935
15936 if (filled)
15937 pAdapter->survey_idx = 1;
15938 else
15939 {
15940 pAdapter->survey_idx = 0;
15941 return -ENONET;
15942 }
15943
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015944 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015945 return 0;
15946}
15947
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015948static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
15949 struct net_device *dev,
15950 int idx, struct survey_info *survey)
15951{
15952 int ret;
15953
15954 vos_ssr_protect(__func__);
15955 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
15956 vos_ssr_unprotect(__func__);
15957
15958 return ret;
15959}
15960
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015961/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015962 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015963 * this is called when cfg80211 driver resume
15964 * driver updates latest sched_scan scan result(if any) to cfg80211 database
15965 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015966int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015967{
15968 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15969 hdd_adapter_t *pAdapter;
15970 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15971 VOS_STATUS status = VOS_STATUS_SUCCESS;
15972
15973 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015974
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015975 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015976 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015977 return 0;
15978 }
15979
15980 spin_lock(&pHddCtx->schedScan_lock);
15981 pHddCtx->isWiphySuspended = FALSE;
15982 if (TRUE != pHddCtx->isSchedScanUpdatePending)
15983 {
15984 spin_unlock(&pHddCtx->schedScan_lock);
15985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15986 "%s: Return resume is not due to PNO indication", __func__);
15987 return 0;
15988 }
15989 // Reset flag to avoid updatating cfg80211 data old results again
15990 pHddCtx->isSchedScanUpdatePending = FALSE;
15991 spin_unlock(&pHddCtx->schedScan_lock);
15992
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015993
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015994 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15995
15996 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15997 {
15998 pAdapter = pAdapterNode->pAdapter;
15999 if ( (NULL != pAdapter) &&
16000 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
16001 {
16002 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016003 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16005 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016006 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016007 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016008 {
16009 /* Acquire wakelock to handle the case where APP's tries to
16010 * suspend immediately after updating the scan results. Whis
16011 * results in app's is in suspended state and not able to
16012 * process the connect request to AP
16013 */
16014 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016015 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016016 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016017
16018 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16019 "%s : cfg80211 scan result database updated", __func__);
16020
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016021 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016022 return 0;
16023
16024 }
16025 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16026 pAdapterNode = pNext;
16027 }
16028
16029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16030 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016031 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016032 return 0;
16033}
16034
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016035int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
16036{
16037 int ret;
16038
16039 vos_ssr_protect(__func__);
16040 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
16041 vos_ssr_unprotect(__func__);
16042
16043 return ret;
16044}
16045
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016046/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016047 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016048 * this is called when cfg80211 driver suspends
16049 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016050int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016051 struct cfg80211_wowlan *wow)
16052{
16053 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016054 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016055
16056 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016057
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016058 ret = wlan_hdd_validate_context(pHddCtx);
16059 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016060 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016061 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016062 }
16063
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016064
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016065 pHddCtx->isWiphySuspended = TRUE;
16066
16067 EXIT();
16068
16069 return 0;
16070}
16071
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016072int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
16073 struct cfg80211_wowlan *wow)
16074{
16075 int ret;
16076
16077 vos_ssr_protect(__func__);
16078 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
16079 vos_ssr_unprotect(__func__);
16080
16081 return ret;
16082}
Jeff Johnson295189b2012-06-20 16:38:30 -070016083/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016084static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070016085{
16086 .add_virtual_intf = wlan_hdd_add_virtual_intf,
16087 .del_virtual_intf = wlan_hdd_del_virtual_intf,
16088 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
16089 .change_station = wlan_hdd_change_station,
16090#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
16091 .add_beacon = wlan_hdd_cfg80211_add_beacon,
16092 .del_beacon = wlan_hdd_cfg80211_del_beacon,
16093 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016094#else
16095 .start_ap = wlan_hdd_cfg80211_start_ap,
16096 .change_beacon = wlan_hdd_cfg80211_change_beacon,
16097 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070016098#endif
16099 .change_bss = wlan_hdd_cfg80211_change_bss,
16100 .add_key = wlan_hdd_cfg80211_add_key,
16101 .get_key = wlan_hdd_cfg80211_get_key,
16102 .del_key = wlan_hdd_cfg80211_del_key,
16103 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016104#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070016105 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016106#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016107 .scan = wlan_hdd_cfg80211_scan,
16108 .connect = wlan_hdd_cfg80211_connect,
16109 .disconnect = wlan_hdd_cfg80211_disconnect,
16110 .join_ibss = wlan_hdd_cfg80211_join_ibss,
16111 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
16112 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
16113 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
16114 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070016115 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
16116 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053016117 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070016118#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16119 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
16120 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
16121 .set_txq_params = wlan_hdd_set_txq_params,
16122#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016123 .get_station = wlan_hdd_cfg80211_get_station,
16124 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
16125 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016126 .add_station = wlan_hdd_cfg80211_add_station,
16127#ifdef FEATURE_WLAN_LFR
16128 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
16129 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
16130 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
16131#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016132#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
16133 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
16134#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016135#ifdef FEATURE_WLAN_TDLS
16136 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
16137 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
16138#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016139#ifdef WLAN_FEATURE_GTK_OFFLOAD
16140 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
16141#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016142#ifdef FEATURE_WLAN_SCAN_PNO
16143 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
16144 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
16145#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016146 .resume = wlan_hdd_cfg80211_resume_wlan,
16147 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016148 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070016149#ifdef WLAN_NL80211_TESTMODE
16150 .testmode_cmd = wlan_hdd_cfg80211_testmode,
16151#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016152 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070016153};
16154