blob: b23399cbdf4aefad5afaee0306a69e0e600459f7 [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) {
Atul Mittal115287b2014-07-08 13:26:33 +05304445 return -EINVAL;
4446 }
4447 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4448
4449 return -ENOTSUPP;
4450 }
4451 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4452 data, data_len,
4453 wlan_hdd_tdls_config_get_status_policy)) {
4454 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4455 return -EINVAL;
4456 }
4457
4458 /* Parse and fetch mac address */
4459 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4460 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4461 return -EINVAL;
4462 }
4463
4464 memcpy(peer, nla_data(
4465 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4466 sizeof(peer));
4467 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4468
4469 ret = wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
4470
4471 if (0 != ret) {
4472 hddLog(VOS_TRACE_LEVEL_ERROR,
4473 FL("get status Failed"));
4474 return -EINVAL;
4475 }
4476 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304477 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304478 NLMSG_HDRLEN);
4479
4480 if (!skb) {
4481 hddLog(VOS_TRACE_LEVEL_ERROR,
4482 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4483 return -EINVAL;
4484 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304485 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 +05304486 reason,
4487 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304488 global_operating_class,
4489 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304490 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304491 if (nla_put_s32(skb,
4492 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4493 state) ||
4494 nla_put_s32(skb,
4495 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4496 reason) ||
4497 nla_put_s32(skb,
4498 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4499 global_operating_class) ||
4500 nla_put_s32(skb,
4501 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4502 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304503
4504 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4505 goto nla_put_failure;
4506 }
4507
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304508 retVal = cfg80211_vendor_cmd_reply(skb);
4509 EXIT();
4510 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05304511
4512nla_put_failure:
4513 kfree_skb(skb);
4514 return -EINVAL;
4515}
4516
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304517static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4518 struct wireless_dev *wdev,
4519 const void *data,
4520 int data_len)
4521{
4522 int ret = 0;
4523
4524 vos_ssr_protect(__func__);
4525 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
4526 vos_ssr_unprotect(__func__);
4527
4528 return ret;
4529}
4530
Atul Mittal115287b2014-07-08 13:26:33 +05304531static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac,
4532 tANI_S32 state,
4533 tANI_S32 reason,
4534 void *ctx)
4535{
4536 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05304537 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304538 tANI_S32 global_operating_class = 0;
4539 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304540 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05304541
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304542 ENTER();
4543
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304544 if (!pAdapter) {
4545 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4546 return -EINVAL;
4547 }
4548
4549 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05304550 if (wlan_hdd_validate_context(pHddCtx)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304551 return -EINVAL;
4552 }
4553
4554 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4555
4556 return -ENOTSUPP;
4557 }
4558 skb = cfg80211_vendor_event_alloc(
4559 pHddCtx->wiphy,
4560 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4561 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4562 GFP_KERNEL);
4563
4564 if (!skb) {
4565 hddLog(VOS_TRACE_LEVEL_ERROR,
4566 FL("cfg80211_vendor_event_alloc failed"));
4567 return -EINVAL;
4568 }
4569 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304570 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4571 reason,
4572 state,
4573 global_operating_class,
4574 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304575 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4576 MAC_ADDR_ARRAY(mac));
4577
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304578 if (nla_put(skb,
4579 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4580 VOS_MAC_ADDR_SIZE, mac) ||
4581 nla_put_s32(skb,
4582 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4583 state) ||
4584 nla_put_s32(skb,
4585 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4586 reason) ||
4587 nla_put_s32(skb,
4588 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4589 channel) ||
4590 nla_put_s32(skb,
4591 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4592 global_operating_class)
4593 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304594 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4595 goto nla_put_failure;
4596 }
4597
4598 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304599 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05304600 return (0);
4601
4602nla_put_failure:
4603 kfree_skb(skb);
4604 return -EINVAL;
4605}
4606
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304607static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304608 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304609 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304610 int data_len)
4611{
4612 u8 peer[6] = {0};
4613 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304614 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4615 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4616 eHalStatus status;
4617 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304618 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304619 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304620
4621 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304622
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304623 if (!dev) {
4624 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4625 return -EINVAL;
4626 }
4627
4628 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4629 if (!pAdapter) {
4630 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4631 return -EINVAL;
4632 }
4633
Atul Mittal115287b2014-07-08 13:26:33 +05304634 status = wlan_hdd_validate_context(pHddCtx);
4635 if (0 != status) {
Atul Mittal115287b2014-07-08 13:26:33 +05304636 return -EINVAL;
4637 }
4638 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4639
4640 return -ENOTSUPP;
4641 }
4642 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4643 data, data_len,
4644 wlan_hdd_tdls_config_enable_policy)) {
4645 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4646 return -EINVAL;
4647 }
4648
4649 /* Parse and fetch mac address */
4650 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4651 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4652 return -EINVAL;
4653 }
4654
4655 memcpy(peer, nla_data(
4656 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4657 sizeof(peer));
4658 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4659
4660 /* Parse and fetch channel */
4661 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4662 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4663 return -EINVAL;
4664 }
4665 pReqMsg.channel = nla_get_s32(
4666 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4667 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4668
4669 /* Parse and fetch global operating class */
4670 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4671 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4672 return -EINVAL;
4673 }
4674 pReqMsg.global_operating_class = nla_get_s32(
4675 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4676 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4677 pReqMsg.global_operating_class);
4678
4679 /* Parse and fetch latency ms */
4680 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4681 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4682 return -EINVAL;
4683 }
4684 pReqMsg.max_latency_ms = nla_get_s32(
4685 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4686 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4687 pReqMsg.max_latency_ms);
4688
4689 /* Parse and fetch required bandwidth kbps */
4690 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4691 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4692 return -EINVAL;
4693 }
4694
4695 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4696 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4697 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4698 pReqMsg.min_bandwidth_kbps);
4699
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304700 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05304701 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05304702 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304703 wlan_hdd_cfg80211_exttdls_callback);
4704
4705 EXIT();
4706 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304707}
4708
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304709static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4710 struct wireless_dev *wdev,
4711 const void *data,
4712 int data_len)
4713{
4714 int ret = 0;
4715
4716 vos_ssr_protect(__func__);
4717 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
4718 vos_ssr_unprotect(__func__);
4719
4720 return ret;
4721}
4722
4723static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304724 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304725 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304726 int data_len)
4727{
4728 u8 peer[6] = {0};
4729 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304730 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4731 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4732 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304733 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304734 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304735
4736 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304737
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304738 if (!dev) {
4739 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4740 return -EINVAL;
4741 }
4742
4743 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4744 if (!pAdapter) {
4745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
4746 return -EINVAL;
4747 }
4748
Atul Mittal115287b2014-07-08 13:26:33 +05304749 status = wlan_hdd_validate_context(pHddCtx);
4750 if (0 != status) {
Atul Mittal115287b2014-07-08 13:26:33 +05304751 return -EINVAL;
4752 }
4753 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4754
4755 return -ENOTSUPP;
4756 }
4757 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4758 data, data_len,
4759 wlan_hdd_tdls_config_disable_policy)) {
4760 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4761 return -EINVAL;
4762 }
4763 /* Parse and fetch mac address */
4764 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4765 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4766 return -EINVAL;
4767 }
4768
4769 memcpy(peer, nla_data(
4770 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4771 sizeof(peer));
4772 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4773
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304774 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
4775
4776 EXIT();
4777 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304778}
4779
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304780static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4781 struct wireless_dev *wdev,
4782 const void *data,
4783 int data_len)
4784{
4785 int ret = 0;
4786
4787 vos_ssr_protect(__func__);
4788 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
4789 vos_ssr_unprotect(__func__);
4790
4791 return ret;
4792}
4793
Dasari Srinivas7875a302014-09-26 17:50:57 +05304794static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304795__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05304796 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304797 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05304798{
4799 struct net_device *dev = wdev->netdev;
4800 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4801 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4802 struct sk_buff *skb = NULL;
4803 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304804 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05304805
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304806 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304807
4808 ret = wlan_hdd_validate_context(pHddCtx);
4809 if (0 != ret)
4810 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304811 return ret;
4812 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05304813 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
4814 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
4815 fset |= WIFI_FEATURE_INFRA;
4816 }
4817
4818 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
4819 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
4820 fset |= WIFI_FEATURE_INFRA_5G;
4821 }
4822
4823#ifdef WLAN_FEATURE_P2P
4824 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
4825 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
4826 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
4827 fset |= WIFI_FEATURE_P2P;
4828 }
4829#endif
4830
4831 /* Soft-AP is supported currently by default */
4832 fset |= WIFI_FEATURE_SOFT_AP;
4833
4834#ifdef WLAN_FEATURE_EXTSCAN
4835 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
4836 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
4837 hddLog(LOG1, FL("EXTScan is supported by firmware"));
4838 fset |= WIFI_FEATURE_EXTSCAN;
4839 }
4840#endif
4841
4842#ifdef WLAN_FEATURE_NAN
4843 if (sme_IsFeatureSupportedByFW(NAN)) {
4844 hddLog(LOG1, FL("NAN is supported by firmware"));
4845 fset |= WIFI_FEATURE_NAN;
4846 }
4847#endif
4848
4849 /* D2D RTT is not supported currently by default */
4850 if (sme_IsFeatureSupportedByFW(RTT)) {
4851 hddLog(LOG1, FL("RTT is supported by firmware"));
4852 fset |= WIFI_FEATURE_D2AP_RTT;
4853 }
4854
4855#ifdef FEATURE_WLAN_BATCH_SCAN
4856 if (fset & WIFI_FEATURE_EXTSCAN) {
4857 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
4858 fset &= ~WIFI_FEATURE_BATCH_SCAN;
4859 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
4860 hddLog(LOG1, FL("Batch scan is supported by firmware"));
4861 fset |= WIFI_FEATURE_BATCH_SCAN;
4862 }
4863#endif
4864
4865#ifdef FEATURE_WLAN_SCAN_PNO
4866 if (pHddCtx->cfg_ini->configPNOScanSupport &&
4867 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
4868 hddLog(LOG1, FL("PNO is supported by firmware"));
4869 fset |= WIFI_FEATURE_PNO;
4870 }
4871#endif
4872
4873 /* STA+STA is supported currently by default */
4874 fset |= WIFI_FEATURE_ADDITIONAL_STA;
4875
4876#ifdef FEATURE_WLAN_TDLS
4877 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
4878 sme_IsFeatureSupportedByFW(TDLS)) {
4879 hddLog(LOG1, FL("TDLS is supported by firmware"));
4880 fset |= WIFI_FEATURE_TDLS;
4881 }
4882
4883 /* TDLS_OFFCHANNEL is not supported currently by default */
4884#endif
4885
4886#ifdef WLAN_AP_STA_CONCURRENCY
4887 /* AP+STA concurrency is supported currently by default */
4888 fset |= WIFI_FEATURE_AP_STA;
4889#endif
4890
4891 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
4892 NLMSG_HDRLEN);
4893
4894 if (!skb) {
4895 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4896 return -EINVAL;
4897 }
4898 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
4899
4900 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
4901 hddLog(LOGE, FL("nla put fail"));
4902 goto nla_put_failure;
4903 }
4904
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304905 ret = cfg80211_vendor_cmd_reply(skb);
4906 EXIT();
4907 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05304908
4909nla_put_failure:
4910 kfree_skb(skb);
4911 return -EINVAL;
4912}
4913
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304914static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304915wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
4916 struct wireless_dev *wdev,
4917 const void *data, int data_len)
4918{
4919 int ret = 0;
4920
4921 vos_ssr_protect(__func__);
4922 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
4923 vos_ssr_unprotect(__func__);
4924
4925 return ret;
4926}
4927
4928static int
4929__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304930 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304931 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304932{
4933 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
4934 uint8_t i, feature_sets, max_feature_sets;
4935 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
4936 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304937 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4938 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304939
4940 ENTER();
4941
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304942 ret = wlan_hdd_validate_context(pHddCtx);
4943 if (0 != ret)
4944 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304945 return ret;
4946 }
4947
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304948 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
4949 data, data_len, NULL)) {
4950 hddLog(LOGE, FL("Invalid ATTR"));
4951 return -EINVAL;
4952 }
4953
4954 /* Parse and fetch max feature set */
4955 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
4956 hddLog(LOGE, FL("Attr max feature set size failed"));
4957 return -EINVAL;
4958 }
4959 max_feature_sets = nla_get_u32(
4960 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
4961 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
4962
4963 /* Fill feature combination matrix */
4964 feature_sets = 0;
4965 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4966 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4967 WIFI_FEATURE_P2P;
4968
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_SOFT_AP;
4972
4973 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4974 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
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_INFRA |
4979 WIFI_FEATURE_SOFT_AP |
4980 WIFI_FEATURE_P2P;
4981
4982 /* Add more feature combinations here */
4983
4984 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
4985 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
4986 hddLog(LOG1, "Feature set matrix");
4987 for (i = 0; i < feature_sets; i++)
4988 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
4989
4990 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4991 sizeof(u32) * feature_sets +
4992 NLMSG_HDRLEN);
4993
4994 if (reply_skb) {
4995 if (nla_put_u32(reply_skb,
4996 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
4997 feature_sets) ||
4998 nla_put(reply_skb,
4999 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5000 sizeof(u32) * feature_sets, feature_set_matrix)) {
5001 hddLog(LOGE, FL("nla put fail"));
5002 kfree_skb(reply_skb);
5003 return -EINVAL;
5004 }
5005
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305006 ret = cfg80211_vendor_cmd_reply(reply_skb);
5007 EXIT();
5008 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305009 }
5010 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5011 return -ENOMEM;
5012
5013max_buffer_err:
5014 hddLog(LOGE, FL("Feature set max buffer size reached. feature_sets(%d) max(%d)"),
5015 feature_sets, WLAN_HDD_MAX_FEATURE_SET);
5016 return -EINVAL;
5017}
5018
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305019static int
5020wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5021 struct wireless_dev *wdev,
5022 const void *data, int data_len)
5023{
5024 int ret = 0;
5025
5026 vos_ssr_protect(__func__);
5027 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5028 data_len);
5029 vos_ssr_unprotect(__func__);
5030
5031 return ret;
5032}
5033
Agarwal Ashish738843c2014-09-25 12:27:56 +05305034static const struct nla_policy
5035wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5036 +1] =
5037{
5038 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5039};
5040
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305041static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305042 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305043 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305044 int data_len)
5045{
5046 struct net_device *dev = wdev->netdev;
5047 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5048 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5049 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5050 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5051 eHalStatus status;
5052 u32 dfsFlag = 0;
5053
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305054 ENTER();
5055
Agarwal Ashish738843c2014-09-25 12:27:56 +05305056 status = wlan_hdd_validate_context(pHddCtx);
5057 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305058 return -EINVAL;
5059 }
5060 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5061 data, data_len,
5062 wlan_hdd_set_no_dfs_flag_config_policy)) {
5063 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5064 return -EINVAL;
5065 }
5066
5067 /* Parse and fetch required bandwidth kbps */
5068 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5069 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5070 return -EINVAL;
5071 }
5072
5073 dfsFlag = nla_get_u32(
5074 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5075 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5076 dfsFlag);
5077
5078 pHddCtx->disable_dfs_flag = dfsFlag;
5079
5080 sme_disable_dfs_channel(hHal, dfsFlag);
5081 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305082
5083 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305084 return 0;
5085}
Atul Mittal115287b2014-07-08 13:26:33 +05305086
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305087static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5088 struct wireless_dev *wdev,
5089 const void *data,
5090 int data_len)
5091{
5092 int ret = 0;
5093
5094 vos_ssr_protect(__func__);
5095 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5096 vos_ssr_unprotect(__func__);
5097
5098 return ret;
5099
5100}
5101
Mukul Sharma2a271632014-10-13 14:59:01 +05305102const struct
5103nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5104{
5105 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5106 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5107};
5108
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305109static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305110 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305111{
5112
5113 u8 bssid[6] = {0};
5114 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5115 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5116 eHalStatus status = eHAL_STATUS_SUCCESS;
5117 v_U32_t isFwrRoamEnabled = FALSE;
5118 int ret;
5119
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305120 ENTER();
5121
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305122 ret = wlan_hdd_validate_context(pHddCtx);
5123 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305124 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305125 }
5126
5127 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5128 data, data_len,
5129 qca_wlan_vendor_attr);
5130 if (ret){
5131 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5132 return -EINVAL;
5133 }
5134
5135 /* Parse and fetch Enable flag */
5136 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5137 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5138 return -EINVAL;
5139 }
5140
5141 isFwrRoamEnabled = nla_get_u32(
5142 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5143
5144 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5145
5146 /* Parse and fetch bssid */
5147 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5148 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5149 return -EINVAL;
5150 }
5151
5152 memcpy(bssid, nla_data(
5153 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5154 sizeof(bssid));
5155 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5156
5157 //Update roaming
5158 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305159 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305160 return status;
5161}
5162
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305163static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5164 struct wireless_dev *wdev, const void *data, int data_len)
5165{
5166 int ret = 0;
5167
5168 vos_ssr_protect(__func__);
5169 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5170 vos_ssr_unprotect(__func__);
5171
5172 return ret;
5173}
5174
Sunil Duttc69bccb2014-05-26 21:30:20 +05305175const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
5176{
Mukul Sharma2a271632014-10-13 14:59:01 +05305177 {
5178 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5179 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
5180 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5181 WIPHY_VENDOR_CMD_NEED_NETDEV |
5182 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305183 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05305184 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305185#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5186 {
5187 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5188 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
5189 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5190 WIPHY_VENDOR_CMD_NEED_NETDEV |
5191 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305192 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05305193 },
5194
5195 {
5196 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5197 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
5198 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5199 WIPHY_VENDOR_CMD_NEED_NETDEV |
5200 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305201 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05305202 },
5203
5204 {
5205 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5206 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
5207 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5208 WIPHY_VENDOR_CMD_NEED_NETDEV |
5209 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305210 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05305211 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305212#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305213#ifdef WLAN_FEATURE_EXTSCAN
5214 {
5215 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5216 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
5217 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5218 WIPHY_VENDOR_CMD_NEED_NETDEV |
5219 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305220 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05305221 },
5222 {
5223 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5224 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
5225 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5226 WIPHY_VENDOR_CMD_NEED_NETDEV |
5227 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305228 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05305229 },
5230 {
5231 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5232 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
5233 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5234 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305235 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05305236 },
5237 {
5238 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5239 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
5240 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5241 WIPHY_VENDOR_CMD_NEED_NETDEV |
5242 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305243 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05305244 },
5245 {
5246 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5247 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
5248 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5249 WIPHY_VENDOR_CMD_NEED_NETDEV |
5250 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305251 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05305252 },
5253 {
5254 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5255 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
5256 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5257 WIPHY_VENDOR_CMD_NEED_NETDEV |
5258 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305259 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305260 },
5261 {
5262 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5263 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
5264 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5265 WIPHY_VENDOR_CMD_NEED_NETDEV |
5266 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305267 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305268 },
5269 {
5270 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5271 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
5272 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5273 WIPHY_VENDOR_CMD_NEED_NETDEV |
5274 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305275 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305276 },
5277 {
5278 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5279 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
5280 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5281 WIPHY_VENDOR_CMD_NEED_NETDEV |
5282 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305283 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305284 },
5285#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305286/*EXT TDLS*/
5287 {
5288 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5289 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
5290 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5291 WIPHY_VENDOR_CMD_NEED_NETDEV |
5292 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305293 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05305294 },
5295 {
5296 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5297 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
5298 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5299 WIPHY_VENDOR_CMD_NEED_NETDEV |
5300 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305301 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05305302 },
5303 {
5304 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5305 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
5306 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5307 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305308 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05305309 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05305310 {
5311 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5312 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
5313 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5314 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305315 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05305316 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05305317 {
5318 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5319 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
5320 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5321 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305322 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05305323 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305324 {
5325 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5326 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
5327 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5328 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305329 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305330 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305331 {
5332 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5333 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
5334 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5335 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305336 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305337 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305338};
5339
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005340/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05305341static const
5342struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005343{
5344#ifdef FEATURE_WLAN_CH_AVOID
5345 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05305346 .vendor_id = QCA_NL80211_VENDOR_ID,
5347 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005348 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305349#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
5350#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5351 {
5352 /* Index = 1*/
5353 .vendor_id = QCA_NL80211_VENDOR_ID,
5354 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
5355 },
5356 {
5357 /* Index = 2*/
5358 .vendor_id = QCA_NL80211_VENDOR_ID,
5359 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
5360 },
5361 {
5362 /* Index = 3*/
5363 .vendor_id = QCA_NL80211_VENDOR_ID,
5364 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
5365 },
5366 {
5367 /* Index = 4*/
5368 .vendor_id = QCA_NL80211_VENDOR_ID,
5369 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
5370 },
5371 {
5372 /* Index = 5*/
5373 .vendor_id = QCA_NL80211_VENDOR_ID,
5374 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
5375 },
5376 {
5377 /* Index = 6*/
5378 .vendor_id = QCA_NL80211_VENDOR_ID,
5379 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
5380 },
5381#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305382#ifdef WLAN_FEATURE_EXTSCAN
5383 {
5384 .vendor_id = QCA_NL80211_VENDOR_ID,
5385 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
5386 },
5387 {
5388 .vendor_id = QCA_NL80211_VENDOR_ID,
5389 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
5390 },
5391 {
5392 .vendor_id = QCA_NL80211_VENDOR_ID,
5393 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
5394 },
5395 {
5396 .vendor_id = QCA_NL80211_VENDOR_ID,
5397 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
5398 },
5399 {
5400 .vendor_id = QCA_NL80211_VENDOR_ID,
5401 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
5402 },
5403 {
5404 .vendor_id = QCA_NL80211_VENDOR_ID,
5405 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
5406 },
5407 {
5408 .vendor_id = QCA_NL80211_VENDOR_ID,
5409 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
5410 },
5411 {
5412 .vendor_id = QCA_NL80211_VENDOR_ID,
5413 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
5414 },
5415 {
5416 .vendor_id = QCA_NL80211_VENDOR_ID,
5417 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
5418 },
5419 {
5420 .vendor_id = QCA_NL80211_VENDOR_ID,
5421 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
5422 },
5423 {
5424 .vendor_id = QCA_NL80211_VENDOR_ID,
5425 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
5426 },
5427 {
5428 .vendor_id = QCA_NL80211_VENDOR_ID,
5429 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
5430 },
5431 {
5432 .vendor_id = QCA_NL80211_VENDOR_ID,
5433 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
5434 },
5435#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305436/*EXT TDLS*/
5437 {
5438 .vendor_id = QCA_NL80211_VENDOR_ID,
5439 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
5440 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005441};
5442
Jeff Johnson295189b2012-06-20 16:38:30 -07005443/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305444 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305445 * This function is called by hdd_wlan_startup()
5446 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305447 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07005448 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305449struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07005450{
5451 struct wiphy *wiphy;
5452 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305453 /*
5454 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07005455 */
5456 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
5457
5458 if (!wiphy)
5459 {
5460 /* Print error and jump into err label and free the memory */
5461 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
5462 return NULL;
5463 }
5464
Sunil Duttc69bccb2014-05-26 21:30:20 +05305465
Jeff Johnson295189b2012-06-20 16:38:30 -07005466 return wiphy;
5467}
5468
5469/*
5470 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305471 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07005472 * private ioctl to change the band value
5473 */
5474int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
5475{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305476 int i, j;
5477 eNVChannelEnabledType channelEnabledState;
5478
Jeff Johnsone7245742012-09-05 17:12:55 -07005479 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305480
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305481 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005482 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305483
5484 if (NULL == wiphy->bands[i])
5485 {
5486 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5487 __func__, i);
5488 continue;
5489 }
5490
5491 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5492 {
5493 struct ieee80211_supported_band *band = wiphy->bands[i];
5494
5495 channelEnabledState = vos_nv_getChannelEnabledState(
5496 band->channels[j].hw_value);
5497
5498 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
5499 {
Abhishek Singh678227a2014-11-04 10:52:38 +05305500 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305501 continue;
5502 }
5503 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
5504 {
5505 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5506 continue;
5507 }
5508
5509 if (NV_CHANNEL_DISABLE == channelEnabledState ||
5510 NV_CHANNEL_INVALID == channelEnabledState)
5511 {
5512 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5513 }
5514 else if (NV_CHANNEL_DFS == channelEnabledState)
5515 {
5516 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5517 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
5518 }
5519 else
5520 {
5521 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
5522 |IEEE80211_CHAN_RADAR);
5523 }
5524 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005525 }
5526 return 0;
5527}
5528/*
5529 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305530 * This function is called by hdd_wlan_startup()
5531 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005532 * This function is used to initialize and register wiphy structure.
5533 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305534int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005535 struct wiphy *wiphy,
5536 hdd_config_t *pCfg
5537 )
5538{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305539 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305540 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5541
Jeff Johnsone7245742012-09-05 17:12:55 -07005542 ENTER();
5543
Jeff Johnson295189b2012-06-20 16:38:30 -07005544 /* Now bind the underlying wlan device with wiphy */
5545 set_wiphy_dev(wiphy, dev);
5546
5547 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005548
Kiet Lam6c583332013-10-14 05:37:09 +05305549#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005550 /* the flag for the other case would be initialzed in
5551 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005552 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305553#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005554
Amar Singhalfddc28c2013-09-05 13:03:40 -07005555 /* This will disable updating of NL channels from passive to
5556 * active if a beacon is received on passive channel. */
5557 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07005558
Amar Singhalfddc28c2013-09-05 13:03:40 -07005559
Amar Singhala49cbc52013-10-08 18:37:44 -07005560
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005561#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005562 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5563 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5564 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005565 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05305566 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005567#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005568
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005569#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005570 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005571#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005572 || pCfg->isFastRoamIniFeatureEnabled
5573#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005574#ifdef FEATURE_WLAN_ESE
5575 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005576#endif
5577 )
5578 {
5579 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5580 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005581#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005582#ifdef FEATURE_WLAN_TDLS
5583 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5584 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5585#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305586#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305587 if (pCfg->configPNOScanSupport)
5588 {
5589 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5590 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5591 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5592 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5593 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305594#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005595
Amar Singhalfddc28c2013-09-05 13:03:40 -07005596#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005597 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5598 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005599 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005600 driver need to determine what to do with both
5601 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005602
5603 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005604#else
5605 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005606#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005607
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305608 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5609
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05305610 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005611
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305612 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5613
Jeff Johnson295189b2012-06-20 16:38:30 -07005614 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305615 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07005616 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07005617 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5618 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005619 | BIT(NL80211_IFTYPE_AP);
5620
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305621 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005622 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305623#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5624 if( pCfg->enableMCC )
5625 {
5626 /* Currently, supports up to two channels */
5627 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005628
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305629 if( !pCfg->allowMCCGODiffBI )
5630 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005631
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305632 }
5633 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5634 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005635#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305636 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005637
Jeff Johnson295189b2012-06-20 16:38:30 -07005638 /* Before registering we need to update the ht capabilitied based
5639 * on ini values*/
5640 if( !pCfg->ShortGI20MhzEnable )
5641 {
5642 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5643 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5644 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5645 }
5646
5647 if( !pCfg->ShortGI40MhzEnable )
5648 {
5649 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5650 }
5651
5652 if( !pCfg->nChannelBondingMode5GHz )
5653 {
5654 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5655 }
5656
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305657 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305658 if (true == hdd_is_5g_supported(pHddCtx))
5659 {
5660 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5661 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305662
5663 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5664 {
5665
5666 if (NULL == wiphy->bands[i])
5667 {
5668 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5669 __func__, i);
5670 continue;
5671 }
5672
5673 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5674 {
5675 struct ieee80211_supported_band *band = wiphy->bands[i];
5676
5677 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5678 {
5679 // Enable social channels for P2P
5680 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5681 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5682 else
5683 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5684 continue;
5685 }
5686 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5687 {
5688 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5689 continue;
5690 }
5691 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005692 }
5693 /*Initialise the supported cipher suite details*/
5694 wiphy->cipher_suites = hdd_cipher_suites;
5695 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5696
5697 /*signal strength in mBm (100*dBm) */
5698 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5699
5700#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305701 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005702#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005703
Sunil Duttc69bccb2014-05-26 21:30:20 +05305704 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
5705 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005706 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
5707 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
5708
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305709 EXIT();
5710 return 0;
5711}
5712
5713/* In this function we are registering wiphy. */
5714int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
5715{
5716 ENTER();
5717 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005718 if (0 > wiphy_register(wiphy))
5719 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305720 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07005721 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
5722 return -EIO;
5723 }
5724
5725 EXIT();
5726 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305727}
Jeff Johnson295189b2012-06-20 16:38:30 -07005728
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305729/* In this function we are updating channel list when,
5730 regulatory domain is FCC and country code is US.
5731 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
5732 As per FCC smart phone is not a indoor device.
5733 GO should not opeate on indoor channels */
5734void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
5735{
5736 int j;
5737 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5738 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
5739 //Default counrtycode from NV at the time of wiphy initialization.
5740 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
5741 &defaultCountryCode[0]))
5742 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005743 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305744 }
5745 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
5746 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305747 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
5748 {
5749 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
5750 return;
5751 }
5752 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
5753 {
5754 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
5755 // Mark UNII -1 band channel as passive
5756 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
5757 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
5758 }
5759 }
5760}
5761
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305762/* This function registers for all frame which supplicant is interested in */
5763void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005764{
Jeff Johnson295189b2012-06-20 16:38:30 -07005765 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5766 /* Register for all P2P action, public action etc frames */
5767 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5768
Jeff Johnsone7245742012-09-05 17:12:55 -07005769 ENTER();
5770
Jeff Johnson295189b2012-06-20 16:38:30 -07005771 /* Right now we are registering these frame when driver is getting
5772 initialized. Once we will move to 2.6.37 kernel, in which we have
5773 frame register ops, we will move this code as a part of that */
5774 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305775 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07005776 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5777
5778 /* GAS Initial Response */
5779 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5780 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305781
Jeff Johnson295189b2012-06-20 16:38:30 -07005782 /* GAS Comeback Request */
5783 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5784 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5785
5786 /* GAS Comeback Response */
5787 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5788 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5789
5790 /* P2P Public Action */
5791 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305792 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005793 P2P_PUBLIC_ACTION_FRAME_SIZE );
5794
5795 /* P2P Action */
5796 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5797 (v_U8_t*)P2P_ACTION_FRAME,
5798 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07005799
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05305800 /* WNM BSS Transition Request frame */
5801 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5802 (v_U8_t*)WNM_BSS_ACTION_FRAME,
5803 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005804
5805 /* WNM-Notification */
5806 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5807 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5808 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005809}
5810
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305811void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005812{
Jeff Johnson295189b2012-06-20 16:38:30 -07005813 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5814 /* Register for all P2P action, public action etc frames */
5815 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5816
Jeff Johnsone7245742012-09-05 17:12:55 -07005817 ENTER();
5818
Jeff Johnson295189b2012-06-20 16:38:30 -07005819 /* Right now we are registering these frame when driver is getting
5820 initialized. Once we will move to 2.6.37 kernel, in which we have
5821 frame register ops, we will move this code as a part of that */
5822 /* GAS Initial Request */
5823
5824 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5825 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5826
5827 /* GAS Initial Response */
5828 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5829 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305830
Jeff Johnson295189b2012-06-20 16:38:30 -07005831 /* GAS Comeback Request */
5832 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5833 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5834
5835 /* GAS Comeback Response */
5836 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5837 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5838
5839 /* P2P Public Action */
5840 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305841 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005842 P2P_PUBLIC_ACTION_FRAME_SIZE );
5843
5844 /* P2P Action */
5845 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5846 (v_U8_t*)P2P_ACTION_FRAME,
5847 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005848 /* WNM-Notification */
5849 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5850 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5851 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005852}
5853
5854#ifdef FEATURE_WLAN_WAPI
5855void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
5856 const u8 *mac_addr, u8 *key , int key_Len)
5857{
5858 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5859 tCsrRoamSetKey setKey;
5860 v_BOOL_t isConnected = TRUE;
5861 int status = 0;
5862 v_U32_t roamId= 0xFF;
5863 tANI_U8 *pKeyPtr = NULL;
5864 int n = 0;
5865
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305866 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
5867 __func__, hdd_device_modetoString(pAdapter->device_mode),
5868 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005869
Gopichand Nakkalae7480202013-02-11 15:24:22 +05305870 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005871 setKey.keyId = key_index; // Store Key ID
5872 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
5873 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
5874 setKey.paeRole = 0 ; // the PAE role
5875 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
5876 {
5877 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
5878 }
5879 else
5880 {
5881 isConnected = hdd_connIsConnected(pHddStaCtx);
5882 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
5883 }
5884 setKey.keyLength = key_Len;
5885 pKeyPtr = setKey.Key;
5886 memcpy( pKeyPtr, key, key_Len);
5887
Arif Hussain6d2a3322013-11-17 19:50:10 -08005888 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005889 __func__, key_Len);
5890 for (n = 0 ; n < key_Len; n++)
5891 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
5892 __func__,n,setKey.Key[n]);
5893
5894 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
5895 if ( isConnected )
5896 {
5897 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
5898 pAdapter->sessionId, &setKey, &roamId );
5899 }
5900 if ( status != 0 )
5901 {
5902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5903 "[%4d] sme_RoamSetKey returned ERROR status= %d",
5904 __LINE__, status );
5905 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
5906 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05305907 /* Need to clear any trace of key value in the memory.
5908 * Thus zero out the memory even though it is local
5909 * variable.
5910 */
5911 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005912}
5913#endif /* FEATURE_WLAN_WAPI*/
5914
5915#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305916int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005917 beacon_data_t **ppBeacon,
5918 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005919#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305920int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005921 beacon_data_t **ppBeacon,
5922 struct cfg80211_beacon_data *params,
5923 int dtim_period)
5924#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305925{
Jeff Johnson295189b2012-06-20 16:38:30 -07005926 int size;
5927 beacon_data_t *beacon = NULL;
5928 beacon_data_t *old = NULL;
5929 int head_len,tail_len;
5930
Jeff Johnsone7245742012-09-05 17:12:55 -07005931 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005932 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305933 {
5934 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5935 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005936 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305937 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005938
5939 old = pAdapter->sessionCtx.ap.beacon;
5940
5941 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305942 {
5943 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5944 FL("session(%d) old and new heads points to NULL"),
5945 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005946 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305947 }
5948
5949 if (params->tail && !params->tail_len)
5950 {
5951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5952 FL("tail_len is zero but tail is not NULL"));
5953 return -EINVAL;
5954 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005955
Jeff Johnson295189b2012-06-20 16:38:30 -07005956#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
5957 /* Kernel 3.0 is not updating dtim_period for set beacon */
5958 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305959 {
5960 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5961 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005962 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305963 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005964#endif
5965
5966 if(params->head)
5967 head_len = params->head_len;
5968 else
5969 head_len = old->head_len;
5970
5971 if(params->tail || !old)
5972 tail_len = params->tail_len;
5973 else
5974 tail_len = old->tail_len;
5975
5976 size = sizeof(beacon_data_t) + head_len + tail_len;
5977
5978 beacon = kzalloc(size, GFP_KERNEL);
5979
5980 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305981 {
5982 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5983 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005984 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305985 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005986
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005987#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005988 if(params->dtim_period || !old )
5989 beacon->dtim_period = params->dtim_period;
5990 else
5991 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005992#else
5993 if(dtim_period || !old )
5994 beacon->dtim_period = dtim_period;
5995 else
5996 beacon->dtim_period = old->dtim_period;
5997#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305998
Jeff Johnson295189b2012-06-20 16:38:30 -07005999 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6000 beacon->tail = beacon->head + head_len;
6001 beacon->head_len = head_len;
6002 beacon->tail_len = tail_len;
6003
6004 if(params->head) {
6005 memcpy (beacon->head,params->head,beacon->head_len);
6006 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306007 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006008 if(old)
6009 memcpy (beacon->head,old->head,beacon->head_len);
6010 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306011
Jeff Johnson295189b2012-06-20 16:38:30 -07006012 if(params->tail) {
6013 memcpy (beacon->tail,params->tail,beacon->tail_len);
6014 }
6015 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306016 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006017 memcpy (beacon->tail,old->tail,beacon->tail_len);
6018 }
6019
6020 *ppBeacon = beacon;
6021
6022 kfree(old);
6023
6024 return 0;
6025
6026}
Jeff Johnson295189b2012-06-20 16:38:30 -07006027
6028v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
6029{
6030 int left = length;
6031 v_U8_t *ptr = pIes;
6032 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306033
Jeff Johnson295189b2012-06-20 16:38:30 -07006034 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306035 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006036 elem_id = ptr[0];
6037 elem_len = ptr[1];
6038 left -= 2;
6039 if(elem_len > left)
6040 {
6041 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006042 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006043 eid,elem_len,left);
6044 return NULL;
6045 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306046 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006047 {
6048 return ptr;
6049 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306050
Jeff Johnson295189b2012-06-20 16:38:30 -07006051 left -= elem_len;
6052 ptr += (elem_len + 2);
6053 }
6054 return NULL;
6055}
6056
Jeff Johnson295189b2012-06-20 16:38:30 -07006057/* Check if rate is 11g rate or not */
6058static int wlan_hdd_rate_is_11g(u8 rate)
6059{
Sanjay Devnani28322e22013-06-21 16:13:40 -07006060 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006061 u8 i;
6062 for (i = 0; i < 8; i++)
6063 {
6064 if(rate == gRateArray[i])
6065 return TRUE;
6066 }
6067 return FALSE;
6068}
6069
6070/* Check for 11g rate and set proper 11g only mode */
6071static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
6072 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
6073{
6074 u8 i, num_rates = pIe[0];
6075
6076 pIe += 1;
6077 for ( i = 0; i < num_rates; i++)
6078 {
6079 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
6080 {
6081 /* If rate set have 11g rate than change the mode to 11G */
6082 *pSapHw_mode = eSAP_DOT11_MODE_11g;
6083 if (pIe[i] & BASIC_RATE_MASK)
6084 {
6085 /* If we have 11g rate as basic rate, it means mode
6086 is 11g only mode.
6087 */
6088 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
6089 *pCheckRatesfor11g = FALSE;
6090 }
6091 }
6092 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6093 {
6094 *require_ht = TRUE;
6095 }
6096 }
6097 return;
6098}
6099
6100static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
6101{
6102 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6103 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6104 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6105 u8 checkRatesfor11g = TRUE;
6106 u8 require_ht = FALSE;
6107 u8 *pIe=NULL;
6108
6109 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
6110
6111 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6112 pBeacon->head_len, WLAN_EID_SUPP_RATES);
6113 if (pIe != NULL)
6114 {
6115 pIe += 1;
6116 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6117 &pConfig->SapHw_mode);
6118 }
6119
6120 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6121 WLAN_EID_EXT_SUPP_RATES);
6122 if (pIe != NULL)
6123 {
6124
6125 pIe += 1;
6126 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6127 &pConfig->SapHw_mode);
6128 }
6129
6130 if( pConfig->channel > 14 )
6131 {
6132 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
6133 }
6134
6135 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6136 WLAN_EID_HT_CAPABILITY);
6137
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306138 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006139 {
6140 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
6141 if(require_ht)
6142 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
6143 }
6144}
6145
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306146static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
6147 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
6148{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006149 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306150 v_U8_t *pIe = NULL;
6151 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6152
6153 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6154 pBeacon->tail, pBeacon->tail_len);
6155
6156 if (pIe)
6157 {
6158 ielen = pIe[1] + 2;
6159 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6160 {
6161 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
6162 }
6163 else
6164 {
6165 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
6166 return -EINVAL;
6167 }
6168 *total_ielen += ielen;
6169 }
6170 return 0;
6171}
6172
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006173static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
6174 v_U8_t *genie, v_U8_t *total_ielen)
6175{
6176 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6177 int left = pBeacon->tail_len;
6178 v_U8_t *ptr = pBeacon->tail;
6179 v_U8_t elem_id, elem_len;
6180 v_U16_t ielen = 0;
6181
6182 if ( NULL == ptr || 0 == left )
6183 return;
6184
6185 while (left >= 2)
6186 {
6187 elem_id = ptr[0];
6188 elem_len = ptr[1];
6189 left -= 2;
6190 if (elem_len > left)
6191 {
6192 hddLog( VOS_TRACE_LEVEL_ERROR,
6193 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
6194 elem_id, elem_len, left);
6195 return;
6196 }
6197 if (IE_EID_VENDOR == elem_id)
6198 {
6199 /* skipping the VSIE's which we don't want to include or
6200 * it will be included by existing code
6201 */
6202 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
6203#ifdef WLAN_FEATURE_WFD
6204 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
6205#endif
6206 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6207 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6208 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
6209 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6210 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
6211 {
6212 ielen = ptr[1] + 2;
6213 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6214 {
6215 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
6216 *total_ielen += ielen;
6217 }
6218 else
6219 {
6220 hddLog( VOS_TRACE_LEVEL_ERROR,
6221 "IE Length is too big "
6222 "IEs eid=%d elem_len=%d total_ie_lent=%d",
6223 elem_id, elem_len, *total_ielen);
6224 }
6225 }
6226 }
6227
6228 left -= elem_len;
6229 ptr += (elem_len + 2);
6230 }
6231 return;
6232}
6233
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006234#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006235static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6236 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006237#else
6238static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6239 struct cfg80211_beacon_data *params)
6240#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006241{
6242 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306243 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006244 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07006245 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006246
6247 genie = vos_mem_malloc(MAX_GENIE_LEN);
6248
6249 if(genie == NULL) {
6250
6251 return -ENOMEM;
6252 }
6253
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306254 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6255 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006256 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306257 hddLog(LOGE,
6258 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306259 ret = -EINVAL;
6260 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006261 }
6262
6263#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306264 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6265 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
6266 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306267 hddLog(LOGE,
6268 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306269 ret = -EINVAL;
6270 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006271 }
6272#endif
6273
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306274 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6275 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006276 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306277 hddLog(LOGE,
6278 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306279 ret = -EINVAL;
6280 goto done;
6281 }
6282
6283 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
6284 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006285 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07006286 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006287
6288 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6289 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
6290 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6291 {
6292 hddLog(LOGE,
6293 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006294 ret = -EINVAL;
6295 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006296 }
6297
6298 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6299 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6300 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6301 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6302 ==eHAL_STATUS_FAILURE)
6303 {
6304 hddLog(LOGE,
6305 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006306 ret = -EINVAL;
6307 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006308 }
6309
6310 // Added for ProResp IE
6311 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
6312 {
6313 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
6314 u8 probe_rsp_ie_len[3] = {0};
6315 u8 counter = 0;
6316 /* Check Probe Resp Length if it is greater then 255 then Store
6317 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
6318 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
6319 Store More then 255 bytes into One Variable.
6320 */
6321 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6322 {
6323 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6324 {
6325 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6326 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6327 }
6328 else
6329 {
6330 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6331 rem_probe_resp_ie_len = 0;
6332 }
6333 }
6334
6335 rem_probe_resp_ie_len = 0;
6336
6337 if (probe_rsp_ie_len[0] > 0)
6338 {
6339 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6340 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6341 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6342 probe_rsp_ie_len[0], NULL,
6343 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6344 {
6345 hddLog(LOGE,
6346 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006347 ret = -EINVAL;
6348 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006349 }
6350 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6351 }
6352
6353 if (probe_rsp_ie_len[1] > 0)
6354 {
6355 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6356 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6357 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6358 probe_rsp_ie_len[1], NULL,
6359 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6360 {
6361 hddLog(LOGE,
6362 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006363 ret = -EINVAL;
6364 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006365 }
6366 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6367 }
6368
6369 if (probe_rsp_ie_len[2] > 0)
6370 {
6371 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6372 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6373 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6374 probe_rsp_ie_len[2], NULL,
6375 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6376 {
6377 hddLog(LOGE,
6378 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006379 ret = -EINVAL;
6380 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006381 }
6382 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6383 }
6384
6385 if (probe_rsp_ie_len[1] == 0 )
6386 {
6387 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6388 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6389 eANI_BOOLEAN_FALSE) )
6390 {
6391 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006392 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006393 }
6394 }
6395
6396 if (probe_rsp_ie_len[2] == 0 )
6397 {
6398 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6399 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6400 eANI_BOOLEAN_FALSE) )
6401 {
6402 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006403 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006404 }
6405 }
6406
6407 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6408 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6409 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6410 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6411 == eHAL_STATUS_FAILURE)
6412 {
6413 hddLog(LOGE,
6414 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006415 ret = -EINVAL;
6416 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006417 }
6418 }
6419 else
6420 {
6421 // Reset WNI_CFG_PROBE_RSP Flags
6422 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
6423
6424 hddLog(VOS_TRACE_LEVEL_INFO,
6425 "%s: No Probe Response IE received in set beacon",
6426 __func__);
6427 }
6428
6429 // Added for AssocResp IE
6430 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
6431 {
6432 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6433 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
6434 params->assocresp_ies_len, NULL,
6435 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6436 {
6437 hddLog(LOGE,
6438 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006439 ret = -EINVAL;
6440 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006441 }
6442
6443 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6444 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
6445 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6446 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6447 == eHAL_STATUS_FAILURE)
6448 {
6449 hddLog(LOGE,
6450 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006451 ret = -EINVAL;
6452 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006453 }
6454 }
6455 else
6456 {
6457 hddLog(VOS_TRACE_LEVEL_INFO,
6458 "%s: No Assoc Response IE received in set beacon",
6459 __func__);
6460
6461 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6462 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6463 eANI_BOOLEAN_FALSE) )
6464 {
6465 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006466 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006467 }
6468 }
6469
Jeff Johnsone7245742012-09-05 17:12:55 -07006470done:
Jeff Johnson295189b2012-06-20 16:38:30 -07006471 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306472 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006473}
Jeff Johnson295189b2012-06-20 16:38:30 -07006474
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306475/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006476 * FUNCTION: wlan_hdd_validate_operation_channel
6477 * called by wlan_hdd_cfg80211_start_bss() and
6478 * wlan_hdd_cfg80211_set_channel()
6479 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306480 * channel list.
6481 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006482VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006483{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306484
Jeff Johnson295189b2012-06-20 16:38:30 -07006485 v_U32_t num_ch = 0;
6486 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6487 u32 indx = 0;
6488 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306489 v_U8_t fValidChannel = FALSE, count = 0;
6490 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306491
Jeff Johnson295189b2012-06-20 16:38:30 -07006492 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6493
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306494 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006495 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306496 /* Validate the channel */
6497 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006498 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306499 if ( channel == rfChannels[count].channelNum )
6500 {
6501 fValidChannel = TRUE;
6502 break;
6503 }
6504 }
6505 if (fValidChannel != TRUE)
6506 {
6507 hddLog(VOS_TRACE_LEVEL_ERROR,
6508 "%s: Invalid Channel [%d]", __func__, channel);
6509 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006510 }
6511 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306512 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006513 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306514 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6515 valid_ch, &num_ch))
6516 {
6517 hddLog(VOS_TRACE_LEVEL_ERROR,
6518 "%s: failed to get valid channel list", __func__);
6519 return VOS_STATUS_E_FAILURE;
6520 }
6521 for (indx = 0; indx < num_ch; indx++)
6522 {
6523 if (channel == valid_ch[indx])
6524 {
6525 break;
6526 }
6527 }
6528
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306529 if (indx >= num_ch)
6530 {
6531 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6532 {
6533 eCsrBand band;
6534 unsigned int freq;
6535
6536 sme_GetFreqBand(hHal, &band);
6537
6538 if (eCSR_BAND_5G == band)
6539 {
6540#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6541 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6542 {
6543 freq = ieee80211_channel_to_frequency(channel,
6544 IEEE80211_BAND_2GHZ);
6545 }
6546 else
6547 {
6548 freq = ieee80211_channel_to_frequency(channel,
6549 IEEE80211_BAND_5GHZ);
6550 }
6551#else
6552 freq = ieee80211_channel_to_frequency(channel);
6553#endif
6554 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6555 return VOS_STATUS_SUCCESS;
6556 }
6557 }
6558
6559 hddLog(VOS_TRACE_LEVEL_ERROR,
6560 "%s: Invalid Channel [%d]", __func__, channel);
6561 return VOS_STATUS_E_FAILURE;
6562 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006563 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306564
Jeff Johnson295189b2012-06-20 16:38:30 -07006565 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306566
Jeff Johnson295189b2012-06-20 16:38:30 -07006567}
6568
Viral Modi3a32cc52013-02-08 11:14:52 -08006569/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306570 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08006571 * This function is used to set the channel number
6572 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306573static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08006574 struct ieee80211_channel *chan,
6575 enum nl80211_channel_type channel_type
6576 )
6577{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306578 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006579 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006580 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006581 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306582 hdd_context_t *pHddCtx;
6583 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006584
6585 ENTER();
6586
6587 if( NULL == dev )
6588 {
6589 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006590 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006591 return -ENODEV;
6592 }
6593 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306594
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306595 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6596 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6597 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006598 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306599 "%s: device_mode = %s (%d) freq = %d", __func__,
6600 hdd_device_modetoString(pAdapter->device_mode),
6601 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306602
6603 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6604 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306605 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006606 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306607 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006608 }
6609
6610 /*
6611 * Do freq to chan conversion
6612 * TODO: for 11a
6613 */
6614
6615 channel = ieee80211_frequency_to_channel(freq);
6616
6617 /* Check freq range */
6618 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6619 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6620 {
6621 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006622 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006623 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6624 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6625 return -EINVAL;
6626 }
6627
6628 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6629
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306630 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6631 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006632 {
6633 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6634 {
6635 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006636 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006637 return -EINVAL;
6638 }
6639 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6640 "%s: set channel to [%d] for device mode =%d",
6641 __func__, channel,pAdapter->device_mode);
6642 }
6643 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006644 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006645 )
6646 {
6647 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6648 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6649 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6650
6651 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6652 {
6653 /* Link is up then return cant set channel*/
6654 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006655 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006656 return -EINVAL;
6657 }
6658
6659 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6660 pHddStaCtx->conn_info.operationChannel = channel;
6661 pRoamProfile->ChannelInfo.ChannelList =
6662 &pHddStaCtx->conn_info.operationChannel;
6663 }
6664 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006665 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006666 )
6667 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306668 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6669 {
6670 if(VOS_STATUS_SUCCESS !=
6671 wlan_hdd_validate_operation_channel(pAdapter,channel))
6672 {
6673 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006674 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306675 return -EINVAL;
6676 }
6677 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6678 }
6679 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006680 {
6681 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6682
6683 /* If auto channel selection is configured as enable/ 1 then ignore
6684 channel set by supplicant
6685 */
6686 if ( cfg_param->apAutoChannelSelection )
6687 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306688 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6689 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006690 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306691 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6692 __func__, hdd_device_modetoString(pAdapter->device_mode),
6693 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006694 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306695 else
6696 {
6697 if(VOS_STATUS_SUCCESS !=
6698 wlan_hdd_validate_operation_channel(pAdapter,channel))
6699 {
6700 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006701 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306702 return -EINVAL;
6703 }
6704 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6705 }
Viral Modi3a32cc52013-02-08 11:14:52 -08006706 }
6707 }
6708 else
6709 {
6710 hddLog(VOS_TRACE_LEVEL_FATAL,
6711 "%s: Invalid device mode failed to set valid channel", __func__);
6712 return -EINVAL;
6713 }
6714 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306715 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006716}
6717
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306718static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
6719 struct net_device *dev,
6720 struct ieee80211_channel *chan,
6721 enum nl80211_channel_type channel_type
6722 )
6723{
6724 int ret;
6725
6726 vos_ssr_protect(__func__);
6727 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
6728 vos_ssr_unprotect(__func__);
6729
6730 return ret;
6731}
6732
Jeff Johnson295189b2012-06-20 16:38:30 -07006733#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6734static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6735 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006736#else
6737static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6738 struct cfg80211_beacon_data *params,
6739 const u8 *ssid, size_t ssid_len,
6740 enum nl80211_hidden_ssid hidden_ssid)
6741#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006742{
6743 tsap_Config_t *pConfig;
6744 beacon_data_t *pBeacon = NULL;
6745 struct ieee80211_mgmt *pMgmt_frame;
6746 v_U8_t *pIe=NULL;
6747 v_U16_t capab_info;
6748 eCsrAuthType RSNAuthType;
6749 eCsrEncryptionType RSNEncryptType;
6750 eCsrEncryptionType mcRSNEncryptType;
6751 int status = VOS_STATUS_SUCCESS;
6752 tpWLAN_SAPEventCB pSapEventCallback;
6753 hdd_hostapd_state_t *pHostapdState;
6754 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
6755 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306756 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006757 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306758 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07006759 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08006760 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05306761 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07006762 v_BOOL_t MFPCapable = VOS_FALSE;
6763 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05306764 v_BOOL_t sapEnable11AC =
6765 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07006766 ENTER();
6767
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306768 iniConfig = pHddCtx->cfg_ini;
6769
Jeff Johnson295189b2012-06-20 16:38:30 -07006770 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
6771
6772 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6773
6774 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6775
6776 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6777
6778 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
6779
6780 //channel is already set in the set_channel Call back
6781 //pConfig->channel = pCommitConfig->channel;
6782
6783 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306784 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07006785 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
6786
6787 pConfig->dtim_period = pBeacon->dtim_period;
6788
Arif Hussain6d2a3322013-11-17 19:50:10 -08006789 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07006790 pConfig->dtim_period);
6791
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08006792 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07006793 {
6794 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006795 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05306796 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
6797 {
6798 tANI_BOOLEAN restartNeeded;
6799 pConfig->ieee80211d = 1;
6800 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
6801 sme_setRegInfo(hHal, pConfig->countryCode);
6802 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
6803 }
6804 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006805 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07006806 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07006807 pConfig->ieee80211d = 1;
6808 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
6809 sme_setRegInfo(hHal, pConfig->countryCode);
6810 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07006811 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006812 else
6813 {
6814 pConfig->ieee80211d = 0;
6815 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306816 /*
6817 * If auto channel is configured i.e. channel is 0,
6818 * so skip channel validation.
6819 */
6820 if( AUTO_CHANNEL_SELECT != pConfig->channel )
6821 {
6822 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
6823 {
6824 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006825 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306826 return -EINVAL;
6827 }
6828 }
6829 else
6830 {
6831 if(1 != pHddCtx->is_dynamic_channel_range_set)
6832 {
6833 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
6834 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
6835 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
6836 }
6837 pHddCtx->is_dynamic_channel_range_set = 0;
6838 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006839 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006840 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006841 {
6842 pConfig->ieee80211d = 0;
6843 }
6844 pConfig->authType = eSAP_AUTO_SWITCH;
6845
6846 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306847
6848 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07006849 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
6850
6851 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
6852
6853 /*Set wps station to configured*/
6854 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
6855
6856 if(pIe)
6857 {
6858 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
6859 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006860 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07006861 return -EINVAL;
6862 }
6863 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
6864 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006865 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07006866 /* Check 15 bit of WPS IE as it contain information for wps state
6867 * WPS state
6868 */
6869 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
6870 {
6871 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
6872 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
6873 {
6874 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
6875 }
6876 }
6877 }
6878 else
6879 {
6880 pConfig->wps_state = SAP_WPS_DISABLED;
6881 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306882 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07006883
c_hpothufe599e92014-06-16 11:38:55 +05306884 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6885 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6886 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
6887 eCSR_ENCRYPT_TYPE_NONE;
6888
Jeff Johnson295189b2012-06-20 16:38:30 -07006889 pConfig->RSNWPAReqIELength = 0;
6890 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306891 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006892 WLAN_EID_RSN);
6893 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306894 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006895 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6896 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6897 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306898 /* The actual processing may eventually be more extensive than
6899 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07006900 * by the app.
6901 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306902 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006903 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6904 &RSNEncryptType,
6905 &mcRSNEncryptType,
6906 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006907 &MFPCapable,
6908 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006909 pConfig->pRSNWPAReqIE[1]+2,
6910 pConfig->pRSNWPAReqIE );
6911
6912 if( VOS_STATUS_SUCCESS == status )
6913 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306914 /* Now copy over all the security attributes you have
6915 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006916 * */
6917 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6918 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6919 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6920 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306921 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006922 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006923 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6924 }
6925 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306926
Jeff Johnson295189b2012-06-20 16:38:30 -07006927 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6928 pBeacon->tail, pBeacon->tail_len);
6929
6930 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
6931 {
6932 if (pConfig->pRSNWPAReqIE)
6933 {
6934 /*Mixed mode WPA/WPA2*/
6935 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
6936 pConfig->RSNWPAReqIELength += pIe[1] + 2;
6937 }
6938 else
6939 {
6940 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6941 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6942 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306943 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006944 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6945 &RSNEncryptType,
6946 &mcRSNEncryptType,
6947 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006948 &MFPCapable,
6949 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006950 pConfig->pRSNWPAReqIE[1]+2,
6951 pConfig->pRSNWPAReqIE );
6952
6953 if( VOS_STATUS_SUCCESS == status )
6954 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306955 /* Now copy over all the security attributes you have
6956 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006957 * */
6958 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6959 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6960 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6961 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306962 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006963 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006964 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6965 }
6966 }
6967 }
6968
Jeff Johnson4416a782013-03-25 14:17:50 -07006969 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
6970 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
6971 return -EINVAL;
6972 }
6973
Jeff Johnson295189b2012-06-20 16:38:30 -07006974 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
6975
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006976#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006977 if (params->ssid != NULL)
6978 {
6979 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
6980 pConfig->SSIDinfo.ssid.length = params->ssid_len;
6981 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6982 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6983 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006984#else
6985 if (ssid != NULL)
6986 {
6987 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
6988 pConfig->SSIDinfo.ssid.length = ssid_len;
6989 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6990 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6991 }
6992#endif
6993
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306994 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07006995 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306996
Jeff Johnson295189b2012-06-20 16:38:30 -07006997 /* default value */
6998 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
6999 pConfig->num_accept_mac = 0;
7000 pConfig->num_deny_mac = 0;
7001
7002 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7003 pBeacon->tail, pBeacon->tail_len);
7004
7005 /* pIe for black list is following form:
7006 type : 1 byte
7007 length : 1 byte
7008 OUI : 4 bytes
7009 acl type : 1 byte
7010 no of mac addr in black list: 1 byte
7011 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307012 */
7013 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007014 {
7015 pConfig->SapMacaddr_acl = pIe[6];
7016 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007017 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007018 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307019 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7020 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007021 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7022 for (i = 0; i < pConfig->num_deny_mac; i++)
7023 {
7024 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7025 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307026 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007027 }
7028 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7029 pBeacon->tail, pBeacon->tail_len);
7030
7031 /* pIe for white list is following form:
7032 type : 1 byte
7033 length : 1 byte
7034 OUI : 4 bytes
7035 acl type : 1 byte
7036 no of mac addr in white list: 1 byte
7037 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307038 */
7039 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007040 {
7041 pConfig->SapMacaddr_acl = pIe[6];
7042 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007043 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007044 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307045 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7046 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007047 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7048 for (i = 0; i < pConfig->num_accept_mac; i++)
7049 {
7050 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7051 acl_entry++;
7052 }
7053 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307054
Jeff Johnson295189b2012-06-20 16:38:30 -07007055 wlan_hdd_set_sapHwmode(pHostapdAdapter);
7056
Jeff Johnsone7245742012-09-05 17:12:55 -07007057#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007058 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307059 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
7060 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05307061 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
7062 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007063 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
7064 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307065 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
7066 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07007067 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307068 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07007069 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307070 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007071
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307072 /* If ACS disable and selected channel <= 14
7073 * OR
7074 * ACS enabled and ACS operating band is choosen as 2.4
7075 * AND
7076 * VHT in 2.4G Disabled
7077 * THEN
7078 * Fallback to 11N mode
7079 */
7080 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
7081 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05307082 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307083 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007084 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307085 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
7086 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007087 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
7088 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007089 }
7090#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307091
Jeff Johnson295189b2012-06-20 16:38:30 -07007092 // ht_capab is not what the name conveys,this is used for protection bitmap
7093 pConfig->ht_capab =
7094 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
7095
7096 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
7097 {
7098 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7099 return -EINVAL;
7100 }
7101
7102 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307103 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07007104 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
7105 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307106 pConfig->obssProtEnabled =
7107 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07007108
Chet Lanctot8cecea22014-02-11 19:09:36 -08007109#ifdef WLAN_FEATURE_11W
7110 pConfig->mfpCapable = MFPCapable;
7111 pConfig->mfpRequired = MFPRequired;
7112 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
7113 pConfig->mfpCapable, pConfig->mfpRequired);
7114#endif
7115
Arif Hussain6d2a3322013-11-17 19:50:10 -08007116 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07007117 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007118 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
7119 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7120 (int)pConfig->channel);
7121 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
7122 pConfig->SapHw_mode, pConfig->privacy,
7123 pConfig->authType);
7124 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
7125 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7126 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7127 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07007128
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307129 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007130 {
7131 //Bss already started. just return.
7132 //TODO Probably it should update some beacon params.
7133 hddLog( LOGE, "Bss Already started...Ignore the request");
7134 EXIT();
7135 return 0;
7136 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307137
Agarwal Ashish51325b52014-06-16 16:50:49 +05307138 if (vos_max_concurrent_connections_reached()) {
7139 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7140 return -EINVAL;
7141 }
7142
Jeff Johnson295189b2012-06-20 16:38:30 -07007143 pConfig->persona = pHostapdAdapter->device_mode;
7144
Peng Xu2446a892014-09-05 17:21:18 +05307145 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
7146 if ( NULL != psmeConfig)
7147 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307148 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05307149 sme_GetConfigParam(hHal, psmeConfig);
7150 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307151#ifdef WLAN_FEATURE_AP_HT40_24G
7152 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7153 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
7154 && pHddCtx->cfg_ini->apHT40_24GEnabled)
7155 {
7156 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
7157 sme_UpdateConfig (hHal, psmeConfig);
7158 }
7159#endif
Peng Xu2446a892014-09-05 17:21:18 +05307160 vos_mem_free(psmeConfig);
7161 }
Peng Xuafc34e32014-09-25 13:23:55 +05307162 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05307163
Jeff Johnson295189b2012-06-20 16:38:30 -07007164 pSapEventCallback = hdd_hostapd_SAPEventCB;
7165 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
7166 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
7167 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007168 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007169 return -EINVAL;
7170 }
7171
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307172 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07007173 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7174
7175 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307176
Jeff Johnson295189b2012-06-20 16:38:30 -07007177 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307178 {
7179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007180 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07007181 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07007182 VOS_ASSERT(0);
7183 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307184
Jeff Johnson295189b2012-06-20 16:38:30 -07007185 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05307186 /* Initialize WMM configuation */
7187 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307188 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007189
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007190#ifdef WLAN_FEATURE_P2P_DEBUG
7191 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
7192 {
7193 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
7194 {
7195 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7196 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007197 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007198 }
7199 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
7200 {
7201 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7202 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007203 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007204 }
7205 }
7206#endif
7207
Jeff Johnson295189b2012-06-20 16:38:30 -07007208 pHostapdState->bCommit = TRUE;
7209 EXIT();
7210
7211 return 0;
7212}
7213
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007214#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307215static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307216 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007217 struct beacon_parameters *params)
7218{
7219 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307220 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307221 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007222
7223 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307224
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307225 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7226 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
7227 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307228 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
7229 hdd_device_modetoString(pAdapter->device_mode),
7230 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007231
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307232 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7233 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307234 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007235 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307236 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007237 }
7238
Agarwal Ashish51325b52014-06-16 16:50:49 +05307239 if (vos_max_concurrent_connections_reached()) {
7240 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7241 return -EINVAL;
7242 }
7243
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307244 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007245 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007246 )
7247 {
7248 beacon_data_t *old,*new;
7249
7250 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307251
Jeff Johnson295189b2012-06-20 16:38:30 -07007252 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307253 {
7254 hddLog(VOS_TRACE_LEVEL_WARN,
7255 FL("already beacon info added to session(%d)"),
7256 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007257 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307258 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007259
7260 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7261
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307262 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07007263 {
7264 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007265 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007266 return -EINVAL;
7267 }
7268
7269 pAdapter->sessionCtx.ap.beacon = new;
7270
7271 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7272 }
7273
7274 EXIT();
7275 return status;
7276}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307277
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307278static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
7279 struct net_device *dev,
7280 struct beacon_parameters *params)
7281{
7282 int ret;
7283
7284 vos_ssr_protect(__func__);
7285 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
7286 vos_ssr_unprotect(__func__);
7287
7288 return ret;
7289}
7290
7291static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007292 struct net_device *dev,
7293 struct beacon_parameters *params)
7294{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307295 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307296 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7297 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307298 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007299
7300 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307301
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307302 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7303 TRACE_CODE_HDD_CFG80211_SET_BEACON,
7304 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
7305 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7306 __func__, hdd_device_modetoString(pAdapter->device_mode),
7307 pAdapter->device_mode);
7308
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307309 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7310 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307311 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007312 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307313 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007314 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307315
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307316 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007317 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307318 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007319 {
7320 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307321
Jeff Johnson295189b2012-06-20 16:38:30 -07007322 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307323
Jeff Johnson295189b2012-06-20 16:38:30 -07007324 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307325 {
7326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7327 FL("session(%d) old and new heads points to NULL"),
7328 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007329 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307330 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007331
7332 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7333
7334 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307335 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007336 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007337 return -EINVAL;
7338 }
7339
7340 pAdapter->sessionCtx.ap.beacon = new;
7341
7342 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7343 }
7344
7345 EXIT();
7346 return status;
7347}
7348
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307349static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
7350 struct net_device *dev,
7351 struct beacon_parameters *params)
7352{
7353 int ret;
7354
7355 vos_ssr_protect(__func__);
7356 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
7357 vos_ssr_unprotect(__func__);
7358
7359 return ret;
7360}
7361
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007362#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7363
7364#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307365static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007366 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007367#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307368static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007369 struct net_device *dev)
7370#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007371{
7372 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07007373 hdd_context_t *pHddCtx = NULL;
7374 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307375 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307376 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007377
7378 ENTER();
7379
7380 if (NULL == pAdapter)
7381 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307382 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007383 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007384 return -ENODEV;
7385 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007386
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307387 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7388 TRACE_CODE_HDD_CFG80211_STOP_AP,
7389 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307390 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7391 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307392 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007393 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307394 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07007395 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007396
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007397 pScanInfo = &pHddCtx->scan_info;
7398
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307399 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7400 __func__, hdd_device_modetoString(pAdapter->device_mode),
7401 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007402
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307403 ret = wlan_hdd_scan_abort(pAdapter);
7404
Girish Gowli4bf7a632014-06-12 13:42:11 +05307405 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07007406 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307407 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7408 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307409
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307410 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07007411 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7413 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08007414
Jeff Johnsone7245742012-09-05 17:12:55 -07007415 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307416 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07007417 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307418 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07007419 }
7420
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05307421 /* Delete all associated STAs before stopping AP/P2P GO */
7422 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05307423 hdd_hostapd_stop(dev);
7424
Jeff Johnson295189b2012-06-20 16:38:30 -07007425 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007426 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007427 )
7428 {
7429 beacon_data_t *old;
7430
7431 old = pAdapter->sessionCtx.ap.beacon;
7432
7433 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307434 {
7435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7436 FL("session(%d) beacon data points to NULL"),
7437 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007438 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307439 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007440
Jeff Johnson295189b2012-06-20 16:38:30 -07007441 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007442
7443 mutex_lock(&pHddCtx->sap_lock);
7444 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7445 {
Jeff Johnson4416a782013-03-25 14:17:50 -07007446 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007447 {
7448 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7449
7450 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7451
7452 if (!VOS_IS_STATUS_SUCCESS(status))
7453 {
7454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007455 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007456 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307457 }
7458 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007459 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307460 /* BSS stopped, clear the active sessions for this device mode */
7461 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007462 }
7463 mutex_unlock(&pHddCtx->sap_lock);
7464
7465 if(status != VOS_STATUS_SUCCESS)
7466 {
7467 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007468 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007469 return -EINVAL;
7470 }
7471
Jeff Johnson4416a782013-03-25 14:17:50 -07007472 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007473 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
7474 ==eHAL_STATUS_FAILURE)
7475 {
7476 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007477 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007478 }
7479
Jeff Johnson4416a782013-03-25 14:17:50 -07007480 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007481 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7482 eANI_BOOLEAN_FALSE) )
7483 {
7484 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007485 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007486 }
7487
7488 // Reset WNI_CFG_PROBE_RSP Flags
7489 wlan_hdd_reset_prob_rspies(pAdapter);
7490
7491 pAdapter->sessionCtx.ap.beacon = NULL;
7492 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007493#ifdef WLAN_FEATURE_P2P_DEBUG
7494 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7495 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7496 {
7497 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7498 "GO got removed");
7499 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7500 }
7501#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007502 }
7503 EXIT();
7504 return status;
7505}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007506
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307507#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7508static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7509 struct net_device *dev)
7510{
7511 int ret;
7512
7513 vos_ssr_protect(__func__);
7514 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7515 vos_ssr_unprotect(__func__);
7516
7517 return ret;
7518}
7519#else
7520static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7521 struct net_device *dev)
7522{
7523 int ret;
7524
7525 vos_ssr_protect(__func__);
7526 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7527 vos_ssr_unprotect(__func__);
7528
7529 return ret;
7530}
7531#endif
7532
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007533#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7534
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307535static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307536 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007537 struct cfg80211_ap_settings *params)
7538{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307539 hdd_adapter_t *pAdapter;
7540 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307541 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007542
7543 ENTER();
7544
Girish Gowlib143d7a2015-02-18 19:39:55 +05307545 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007546 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05307548 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307549 return -ENODEV;
7550 }
7551
7552 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7553 if (NULL == pAdapter)
7554 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307556 "%s: HDD adapter is Null", __func__);
7557 return -ENODEV;
7558 }
7559
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307560 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7561 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
7562 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307563 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7564 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307566 "%s: HDD adapter magic is invalid", __func__);
7567 return -ENODEV;
7568 }
7569
7570 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307571 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307572 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307573 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307574 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307575 }
7576
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307577 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7578 __func__, hdd_device_modetoString(pAdapter->device_mode),
7579 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307580
7581 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007582 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007583 )
7584 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307585 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007586
7587 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307588
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007589 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307590 {
7591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7592 FL("already beacon info added to session(%d)"),
7593 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007594 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307595 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007596
Girish Gowlib143d7a2015-02-18 19:39:55 +05307597#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7598 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7599 &new,
7600 &params->beacon);
7601#else
7602 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7603 &new,
7604 &params->beacon,
7605 params->dtim_period);
7606#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007607
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307608 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007609 {
7610 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307611 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007612 return -EINVAL;
7613 }
7614 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007615#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007616 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7617#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7618 params->channel, params->channel_type);
7619#else
7620 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7621#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007622#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007623 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
7624 params->ssid_len, params->hidden_ssid);
7625 }
7626
7627 EXIT();
7628 return status;
7629}
7630
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307631static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7632 struct net_device *dev,
7633 struct cfg80211_ap_settings *params)
7634{
7635 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007636
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307637 vos_ssr_protect(__func__);
7638 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
7639 vos_ssr_unprotect(__func__);
7640
7641 return ret;
7642}
7643
7644static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007645 struct net_device *dev,
7646 struct cfg80211_beacon_data *params)
7647{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307648 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307649 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307650 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007651
7652 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307653
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307654 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7655 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7656 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007657 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007658 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307659
7660 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7661 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307662 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007663 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307664 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007665 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007666
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307667 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007668 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307669 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007670 {
7671 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307672
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007673 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307674
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007675 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307676 {
7677 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7678 FL("session(%d) beacon data points to NULL"),
7679 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007680 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307681 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007682
7683 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
7684
7685 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307686 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007687 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007688 return -EINVAL;
7689 }
7690
7691 pAdapter->sessionCtx.ap.beacon = new;
7692
7693 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
7694 }
7695
7696 EXIT();
7697 return status;
7698}
7699
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307700static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
7701 struct net_device *dev,
7702 struct cfg80211_beacon_data *params)
7703{
7704 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007705
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307706 vos_ssr_protect(__func__);
7707 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
7708 vos_ssr_unprotect(__func__);
7709
7710 return ret;
7711}
7712
7713#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007714
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307715static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007716 struct net_device *dev,
7717 struct bss_parameters *params)
7718{
7719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307720 hdd_context_t *pHddCtx;
7721 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007722
7723 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307724
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307725 if (NULL == pAdapter)
7726 {
7727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7728 "%s: HDD adapter is Null", __func__);
7729 return -ENODEV;
7730 }
7731 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307732 ret = wlan_hdd_validate_context(pHddCtx);
7733 if (0 != ret)
7734 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307735 return ret;
7736 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307737 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7738 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
7739 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307740 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7741 __func__, hdd_device_modetoString(pAdapter->device_mode),
7742 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007743
7744 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007745 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307746 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007747 {
7748 /* ap_isolate == -1 means that in change bss, upper layer doesn't
7749 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307750 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07007751 {
7752 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307753 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007754 }
7755
7756 EXIT();
7757 return 0;
7758}
7759
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307760static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
7761 struct net_device *dev,
7762 struct bss_parameters *params)
7763{
7764 int ret;
7765
7766 vos_ssr_protect(__func__);
7767 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
7768 vos_ssr_unprotect(__func__);
7769
7770 return ret;
7771}
Kiet Lam10841362013-11-01 11:36:50 +05307772/* FUNCTION: wlan_hdd_change_country_code_cd
7773* to wait for contry code completion
7774*/
7775void* wlan_hdd_change_country_code_cb(void *pAdapter)
7776{
7777 hdd_adapter_t *call_back_pAdapter = pAdapter;
7778 complete(&call_back_pAdapter->change_country_code);
7779 return NULL;
7780}
7781
Jeff Johnson295189b2012-06-20 16:38:30 -07007782/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307783 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07007784 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
7785 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307786int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007787 struct net_device *ndev,
7788 enum nl80211_iftype type,
7789 u32 *flags,
7790 struct vif_params *params
7791 )
7792{
7793 struct wireless_dev *wdev;
7794 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007795 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07007796 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007797 tCsrRoamProfile *pRoamProfile = NULL;
7798 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307799 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007800 eMib_dot11DesiredBssType connectedBssType;
7801 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307802 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007803
7804 ENTER();
7805
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307806 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007807 {
7808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7809 "%s: Adapter context is null", __func__);
7810 return VOS_STATUS_E_FAILURE;
7811 }
7812
7813 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7814 if (!pHddCtx)
7815 {
7816 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7817 "%s: HDD context is null", __func__);
7818 return VOS_STATUS_E_FAILURE;
7819 }
7820
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307821 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7822 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
7823 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307824 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307825 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007826 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307827 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007828 }
7829
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307830 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7831 __func__, hdd_device_modetoString(pAdapter->device_mode),
7832 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007833
Agarwal Ashish51325b52014-06-16 16:50:49 +05307834 if (vos_max_concurrent_connections_reached()) {
7835 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7836 return -EINVAL;
7837 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307838 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007839 wdev = ndev->ieee80211_ptr;
7840
7841#ifdef WLAN_BTAMP_FEATURE
7842 if((NL80211_IFTYPE_P2P_CLIENT == type)||
7843 (NL80211_IFTYPE_ADHOC == type)||
7844 (NL80211_IFTYPE_AP == type)||
7845 (NL80211_IFTYPE_P2P_GO == type))
7846 {
7847 pHddCtx->isAmpAllowed = VOS_FALSE;
7848 // stop AMP traffic
7849 status = WLANBAP_StopAmp();
7850 if(VOS_STATUS_SUCCESS != status )
7851 {
7852 pHddCtx->isAmpAllowed = VOS_TRUE;
7853 hddLog(VOS_TRACE_LEVEL_FATAL,
7854 "%s: Failed to stop AMP", __func__);
7855 return -EINVAL;
7856 }
7857 }
7858#endif //WLAN_BTAMP_FEATURE
7859 /* Reset the current device mode bit mask*/
7860 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7861
7862 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007863 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07007864 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07007865 )
7866 {
7867 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007868 if (!pWextState)
7869 {
7870 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7871 "%s: pWextState is null", __func__);
7872 return VOS_STATUS_E_FAILURE;
7873 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007874 pRoamProfile = &pWextState->roamProfile;
7875 LastBSSType = pRoamProfile->BSSType;
7876
7877 switch (type)
7878 {
7879 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007880 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007881 hddLog(VOS_TRACE_LEVEL_INFO,
7882 "%s: setting interface Type to INFRASTRUCTURE", __func__);
7883 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07007884#ifdef WLAN_FEATURE_11AC
7885 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
7886 {
7887 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
7888 }
7889#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307890 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07007891 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007892 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007893 //Check for sub-string p2p to confirm its a p2p interface
7894 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307895 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007896 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7897 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7898 }
7899 else
7900 {
7901 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007902 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007903 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007904 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05307905
Jeff Johnson295189b2012-06-20 16:38:30 -07007906 case NL80211_IFTYPE_ADHOC:
7907 hddLog(VOS_TRACE_LEVEL_INFO,
7908 "%s: setting interface Type to ADHOC", __func__);
7909 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
7910 pRoamProfile->phyMode =
7911 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07007912 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007913 wdev->iftype = type;
7914 break;
7915
7916 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007917 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007918 {
7919 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7920 "%s: setting interface Type to %s", __func__,
7921 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
7922
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007923 //Cancel any remain on channel for GO mode
7924 if (NL80211_IFTYPE_P2P_GO == type)
7925 {
7926 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
7927 }
Mohit Khanna0f232092012-09-11 14:46:08 -07007928 if (NL80211_IFTYPE_AP == type)
7929 {
7930 /* As Loading WLAN Driver one interface being created for p2p device
7931 * address. This will take one HW STA and the max number of clients
7932 * that can connect to softAP will be reduced by one. so while changing
7933 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
7934 * interface as it is not required in SoftAP mode.
7935 */
7936
7937 // Get P2P Adapter
7938 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
7939
7940 if (pP2pAdapter)
7941 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307942 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05307943 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07007944 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
7945 }
7946 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05307947 //Disable IMPS & BMPS for SAP/GO
7948 if(VOS_STATUS_E_FAILURE ==
7949 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
7950 {
7951 //Fail to Exit BMPS
7952 VOS_ASSERT(0);
7953 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05307954
7955 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
7956
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307957#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07007958
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307959 /* A Mutex Lock is introduced while changing the mode to
7960 * protect the concurrent access for the Adapters by TDLS
7961 * module.
7962 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307963 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307964#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007965 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05307966 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07007967 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07007968 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7969 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307970#ifdef FEATURE_WLAN_TDLS
7971 mutex_unlock(&pHddCtx->tdls_lock);
7972#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007973 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
7974 (pConfig->apRandomBssidEnabled))
7975 {
7976 /* To meet Android requirements create a randomized
7977 MAC address of the form 02:1A:11:Fx:xx:xx */
7978 get_random_bytes(&ndev->dev_addr[3], 3);
7979 ndev->dev_addr[0] = 0x02;
7980 ndev->dev_addr[1] = 0x1A;
7981 ndev->dev_addr[2] = 0x11;
7982 ndev->dev_addr[3] |= 0xF0;
7983 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
7984 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08007985 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
7986 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007987 }
7988
Jeff Johnson295189b2012-06-20 16:38:30 -07007989 hdd_set_ap_ops( pAdapter->dev );
7990
Kiet Lam10841362013-11-01 11:36:50 +05307991 /* This is for only SAP mode where users can
7992 * control country through ini.
7993 * P2P GO follows station country code
7994 * acquired during the STA scanning. */
7995 if((NL80211_IFTYPE_AP == type) &&
7996 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
7997 {
7998 int status = 0;
7999 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
8000 "%s: setting country code from INI ", __func__);
8001 init_completion(&pAdapter->change_country_code);
8002 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
8003 (void *)(tSmeChangeCountryCallback)
8004 wlan_hdd_change_country_code_cb,
8005 pConfig->apCntryCode, pAdapter,
8006 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308007 eSIR_FALSE,
8008 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05308009 if (eHAL_STATUS_SUCCESS == status)
8010 {
8011 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308012 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05308013 &pAdapter->change_country_code,
8014 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308015 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05308016 {
8017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308018 FL("SME Timed out while setting country code %ld"),
8019 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08008020
8021 if (pHddCtx->isLogpInProgress)
8022 {
8023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8024 "%s: LOGP in Progress. Ignore!!!", __func__);
8025 return -EAGAIN;
8026 }
Kiet Lam10841362013-11-01 11:36:50 +05308027 }
8028 }
8029 else
8030 {
8031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008032 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05308033 return -EINVAL;
8034 }
8035 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008036 status = hdd_init_ap_mode(pAdapter);
8037 if(status != VOS_STATUS_SUCCESS)
8038 {
8039 hddLog(VOS_TRACE_LEVEL_FATAL,
8040 "%s: Error initializing the ap mode", __func__);
8041 return -EINVAL;
8042 }
8043 hdd_set_conparam(1);
8044
Jeff Johnson295189b2012-06-20 16:38:30 -07008045 /*interface type changed update in wiphy structure*/
8046 if(wdev)
8047 {
8048 wdev->iftype = type;
8049 pHddCtx->change_iface = type;
8050 }
8051 else
8052 {
8053 hddLog(VOS_TRACE_LEVEL_ERROR,
8054 "%s: ERROR !!!! Wireless dev is NULL", __func__);
8055 return -EINVAL;
8056 }
8057 goto done;
8058 }
8059
8060 default:
8061 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8062 __func__);
8063 return -EOPNOTSUPP;
8064 }
8065 }
8066 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008067 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008068 )
8069 {
8070 switch(type)
8071 {
8072 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008073 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008074 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05308075
8076 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308077#ifdef FEATURE_WLAN_TDLS
8078
8079 /* A Mutex Lock is introduced while changing the mode to
8080 * protect the concurrent access for the Adapters by TDLS
8081 * module.
8082 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308083 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308084#endif
c_hpothu002231a2015-02-05 14:58:51 +05308085 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008086 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008087 //Check for sub-string p2p to confirm its a p2p interface
8088 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008089 {
8090 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8091 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8092 }
8093 else
8094 {
8095 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008096 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008097 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008098 hdd_set_conparam(0);
8099 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008100 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
8101 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308102#ifdef FEATURE_WLAN_TDLS
8103 mutex_unlock(&pHddCtx->tdls_lock);
8104#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308105 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008106 if( VOS_STATUS_SUCCESS != status )
8107 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07008108 /* In case of JB, for P2P-GO, only change interface will be called,
8109 * This is the right place to enable back bmps_imps()
8110 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308111 if (pHddCtx->hdd_wlan_suspended)
8112 {
8113 hdd_set_pwrparams(pHddCtx);
8114 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008115 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008116 goto done;
8117 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008118 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008119 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008120 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8121 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008122 goto done;
8123 default:
8124 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8125 __func__);
8126 return -EOPNOTSUPP;
8127
8128 }
8129
8130 }
8131 else
8132 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308133 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
8134 __func__, hdd_device_modetoString(pAdapter->device_mode),
8135 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008136 return -EOPNOTSUPP;
8137 }
8138
8139
8140 if(pRoamProfile)
8141 {
8142 if ( LastBSSType != pRoamProfile->BSSType )
8143 {
8144 /*interface type changed update in wiphy structure*/
8145 wdev->iftype = type;
8146
8147 /*the BSS mode changed, We need to issue disconnect
8148 if connected or in IBSS disconnect state*/
8149 if ( hdd_connGetConnectedBssType(
8150 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
8151 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
8152 {
8153 /*need to issue a disconnect to CSR.*/
8154 INIT_COMPLETION(pAdapter->disconnect_comp_var);
8155 if( eHAL_STATUS_SUCCESS ==
8156 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
8157 pAdapter->sessionId,
8158 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
8159 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308160 ret = wait_for_completion_interruptible_timeout(
8161 &pAdapter->disconnect_comp_var,
8162 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
8163 if (ret <= 0)
8164 {
8165 hddLog(VOS_TRACE_LEVEL_ERROR,
8166 FL("wait on disconnect_comp_var failed %ld"), ret);
8167 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008168 }
8169 }
8170 }
8171 }
8172
8173done:
8174 /*set bitmask based on updated value*/
8175 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07008176
8177 /* Only STA mode support TM now
8178 * all other mode, TM feature should be disabled */
8179 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
8180 (~VOS_STA & pHddCtx->concurrency_mode) )
8181 {
8182 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
8183 }
8184
Jeff Johnson295189b2012-06-20 16:38:30 -07008185#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308186 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05308187 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07008188 {
8189 //we are ok to do AMP
8190 pHddCtx->isAmpAllowed = VOS_TRUE;
8191 }
8192#endif //WLAN_BTAMP_FEATURE
8193 EXIT();
8194 return 0;
8195}
8196
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308197/*
8198 * FUNCTION: wlan_hdd_cfg80211_change_iface
8199 * wrapper function to protect the actual implementation from SSR.
8200 */
8201int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
8202 struct net_device *ndev,
8203 enum nl80211_iftype type,
8204 u32 *flags,
8205 struct vif_params *params
8206 )
8207{
8208 int ret;
8209
8210 vos_ssr_protect(__func__);
8211 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
8212 vos_ssr_unprotect(__func__);
8213
8214 return ret;
8215}
8216
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008217#ifdef FEATURE_WLAN_TDLS
8218static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
8219 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
8220{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008221 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8222 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008223 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308224 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308225 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308226 hdd_adapter_t *pAdapter;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008227
8228 ENTER();
8229
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308230 if (!dev) {
8231 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
8232 return -EINVAL;
8233 }
8234
8235 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8236 if (!pAdapter) {
8237 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
8238 return -EINVAL;
8239 }
8240
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308241 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008242 {
8243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8244 "Invalid arguments");
8245 return -EINVAL;
8246 }
Hoonki Lee27511902013-03-14 18:19:06 -07008247
8248 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
8249 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
8250 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07008252 "%s: TDLS mode is disabled OR not enabled in FW."
8253 MAC_ADDRESS_STR " Request declined.",
8254 __func__, MAC_ADDR_ARRAY(mac));
8255 return -ENOTSUPP;
8256 }
8257
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008258 if (pHddCtx->isLogpInProgress)
8259 {
8260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8261 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05308262 wlan_hdd_tdls_set_link_status(pAdapter,
8263 mac,
8264 eTDLS_LINK_IDLE,
8265 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008266 return -EBUSY;
8267 }
8268
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05308269 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008270
8271 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308272 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008273 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
8274 __func__, MAC_ADDR_ARRAY(mac), update);
8275 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008276 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008277
8278 /* in add station, we accept existing valid staId if there is */
8279 if ((0 == update) &&
8280 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
8281 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008282 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008284 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008285 " link_status %d. staId %d. add station ignored.",
8286 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
8287 return 0;
8288 }
8289 /* in change station, we accept only when staId is valid */
8290 if ((1 == update) &&
8291 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
8292 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
8293 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008295 "%s: " MAC_ADDRESS_STR
8296 " link status %d. staId %d. change station %s.",
8297 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
8298 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
8299 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008300 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008301
8302 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308303 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008304 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008305 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8306 "%s: " MAC_ADDRESS_STR
8307 " TDLS setup is ongoing. Request declined.",
8308 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07008309 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008310 }
8311
8312 /* first to check if we reached to maximum supported TDLS peer.
8313 TODO: for now, return -EPERM looks working fine,
8314 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308315 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8316 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008317 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8319 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308320 " TDLS Max peer already connected. Request declined."
8321 " Num of peers (%d), Max allowed (%d).",
8322 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
8323 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008324 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008325 }
8326 else
8327 {
8328 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308329 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008330 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008331 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008332 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8333 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
8334 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008335 return -EPERM;
8336 }
8337 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008338 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05308339 wlan_hdd_tdls_set_link_status(pAdapter,
8340 mac,
8341 eTDLS_LINK_CONNECTING,
8342 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008343
Jeff Johnsond75fe012013-04-06 10:53:06 -07008344 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308345 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008346 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008348 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008349 if(StaParams->htcap_present)
8350 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008352 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008354 "ht_capa->extended_capabilities: %0x",
8355 StaParams->HTCap.extendedHtCapInfo);
8356 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008358 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308359 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008360 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008361 if(StaParams->vhtcap_present)
8362 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308363 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008364 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
8365 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
8366 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
8367 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008368 {
8369 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008371 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308372 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008373 "[%d]: %x ", i, StaParams->supported_rates[i]);
8374 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07008375 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308376 else if ((1 == update) && (NULL == StaParams))
8377 {
8378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8379 "%s : update is true, but staParams is NULL. Error!", __func__);
8380 return -EPERM;
8381 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008382
8383 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
8384
8385 if (!update)
8386 {
8387 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
8388 pAdapter->sessionId, mac);
8389 }
8390 else
8391 {
8392 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
8393 pAdapter->sessionId, mac, StaParams);
8394 }
8395
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308396 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008397 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
8398
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308399 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008400 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308402 "%s: timeout waiting for tdls add station indication %ld",
8403 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008404 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008405 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308406
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008407 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
8408 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008410 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008411 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008412 }
8413
8414 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008415
8416error:
Atul Mittal115287b2014-07-08 13:26:33 +05308417 wlan_hdd_tdls_set_link_status(pAdapter,
8418 mac,
8419 eTDLS_LINK_IDLE,
8420 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008421 return -EPERM;
8422
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008423}
8424#endif
8425
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308426static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008427 struct net_device *dev,
8428 u8 *mac,
8429 struct station_parameters *params)
8430{
8431 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308432 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308433 hdd_context_t *pHddCtx;
8434 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008435 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308436 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008437#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008438 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008439 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308440 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008441#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008442
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308443 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308444
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308445 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308446 if ((NULL == pAdapter))
8447 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308449 "invalid adapter ");
8450 return -EINVAL;
8451 }
8452
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308453 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8454 TRACE_CODE_HDD_CHANGE_STATION,
8455 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05308456 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308457
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308458 ret = wlan_hdd_validate_context(pHddCtx);
8459 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05308460 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308461 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308462 }
8463
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308464 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8465
8466 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008467 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8469 "invalid HDD station context");
8470 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008471 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008472 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
8473
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008474 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8475 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07008476 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008477 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07008478 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308479 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07008480 WLANTL_STA_AUTHENTICATED);
8481
Gopichand Nakkala29149562013-05-10 21:43:41 +05308482 if (status != VOS_STATUS_SUCCESS)
8483 {
8484 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8485 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8486 return -EINVAL;
8487 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008488 }
8489 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008490 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8491 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308492#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008493 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8494 StaParams.capability = params->capability;
8495 StaParams.uapsd_queues = params->uapsd_queues;
8496 StaParams.max_sp = params->max_sp;
8497
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308498 /* Convert (first channel , number of channels) tuple to
8499 * the total list of channels. This goes with the assumption
8500 * that if the first channel is < 14, then the next channels
8501 * are an incremental of 1 else an incremental of 4 till the number
8502 * of channels.
8503 */
8504 if (0 != params->supported_channels_len) {
8505 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8506 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8507 {
8508 int wifi_chan_index;
8509 StaParams.supported_channels[j] = params->supported_channels[i];
8510 wifi_chan_index =
8511 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8512 no_of_channels = params->supported_channels[i+1];
8513 for(k=1; k <= no_of_channels; k++)
8514 {
8515 StaParams.supported_channels[j+1] =
8516 StaParams.supported_channels[j] + wifi_chan_index;
8517 j+=1;
8518 }
8519 }
8520 StaParams.supported_channels_len = j;
8521 }
8522 vos_mem_copy(StaParams.supported_oper_classes,
8523 params->supported_oper_classes,
8524 params->supported_oper_classes_len);
8525 StaParams.supported_oper_classes_len =
8526 params->supported_oper_classes_len;
8527
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008528 if (0 != params->ext_capab_len)
8529 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8530 sizeof(StaParams.extn_capability));
8531
8532 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008533 {
8534 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008535 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008536 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008537
8538 StaParams.supported_rates_len = params->supported_rates_len;
8539
8540 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8541 * The supported_rates array , for all the structures propogating till Add Sta
8542 * to the firmware has to be modified , if the supplicant (ieee80211) is
8543 * modified to send more rates.
8544 */
8545
8546 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8547 */
8548 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8549 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8550
8551 if (0 != StaParams.supported_rates_len) {
8552 int i = 0;
8553 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8554 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008556 "Supported Rates with Length %d", StaParams.supported_rates_len);
8557 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008559 "[%d]: %0x", i, StaParams.supported_rates[i]);
8560 }
8561
8562 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008563 {
8564 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008565 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008566 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008567
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008568 if (0 != params->ext_capab_len ) {
8569 /*Define A Macro : TODO Sunil*/
8570 if ((1<<4) & StaParams.extn_capability[3]) {
8571 isBufSta = 1;
8572 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308573 /* TDLS Channel Switching Support */
8574 if ((1<<6) & StaParams.extn_capability[3]) {
8575 isOffChannelSupported = 1;
8576 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008577 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308578 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8579 &StaParams, isBufSta,
8580 isOffChannelSupported);
8581
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308582 if (VOS_STATUS_SUCCESS != status) {
8583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8584 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8585 return -EINVAL;
8586 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008587 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8588
8589 if (VOS_STATUS_SUCCESS != status) {
8590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8591 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8592 return -EINVAL;
8593 }
8594 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008595#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308596 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008597 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008598 return status;
8599}
8600
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308601static int wlan_hdd_change_station(struct wiphy *wiphy,
8602 struct net_device *dev,
8603 u8 *mac,
8604 struct station_parameters *params)
8605{
8606 int ret;
8607
8608 vos_ssr_protect(__func__);
8609 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
8610 vos_ssr_unprotect(__func__);
8611
8612 return ret;
8613}
8614
Jeff Johnson295189b2012-06-20 16:38:30 -07008615/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308616 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008617 * This function is used to initialize the key information
8618 */
8619#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308620static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008621 struct net_device *ndev,
8622 u8 key_index, bool pairwise,
8623 const u8 *mac_addr,
8624 struct key_params *params
8625 )
8626#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308627static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008628 struct net_device *ndev,
8629 u8 key_index, const u8 *mac_addr,
8630 struct key_params *params
8631 )
8632#endif
8633{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008634 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07008635 tCsrRoamSetKey setKey;
8636 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308637 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008638 v_U32_t roamId= 0xFF;
8639 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008640 hdd_hostapd_state_t *pHostapdState;
8641 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008642 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308643 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008644
8645 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308646
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308647 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8648 TRACE_CODE_HDD_CFG80211_ADD_KEY,
8649 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308650 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8651 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308652 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008653 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308654 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008655 }
8656
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308657 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8658 __func__, hdd_device_modetoString(pAdapter->device_mode),
8659 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008660
8661 if (CSR_MAX_NUM_KEY <= key_index)
8662 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008663 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008664 key_index);
8665
8666 return -EINVAL;
8667 }
8668
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008669 if (CSR_MAX_KEY_LEN < params->key_len)
8670 {
8671 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
8672 params->key_len);
8673
8674 return -EINVAL;
8675 }
8676
8677 hddLog(VOS_TRACE_LEVEL_INFO,
8678 "%s: called with key index = %d & key length %d",
8679 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008680
8681 /*extract key idx, key len and key*/
8682 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8683 setKey.keyId = key_index;
8684 setKey.keyLength = params->key_len;
8685 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
8686
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008687 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07008688 {
8689 case WLAN_CIPHER_SUITE_WEP40:
8690 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
8691 break;
8692
8693 case WLAN_CIPHER_SUITE_WEP104:
8694 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
8695 break;
8696
8697 case WLAN_CIPHER_SUITE_TKIP:
8698 {
8699 u8 *pKey = &setKey.Key[0];
8700 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
8701
8702 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
8703
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008704 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07008705
8706 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008707 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008708 |--------------|----------|----------|
8709 <---16bytes---><--8bytes--><--8bytes-->
8710
8711 */
8712 /*Sme expects the 32 bytes key to be in the below order
8713
8714 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008715 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008716 |--------------|----------|----------|
8717 <---16bytes---><--8bytes--><--8bytes-->
8718 */
8719 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008720 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07008721
8722 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008723 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008724
8725 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008726 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008727
8728
8729 break;
8730 }
8731
8732 case WLAN_CIPHER_SUITE_CCMP:
8733 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
8734 break;
8735
8736#ifdef FEATURE_WLAN_WAPI
8737 case WLAN_CIPHER_SUITE_SMS4:
8738 {
8739 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8740 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
8741 params->key, params->key_len);
8742 return 0;
8743 }
8744#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008745
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008746#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07008747 case WLAN_CIPHER_SUITE_KRK:
8748 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
8749 break;
8750#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008751
8752#ifdef WLAN_FEATURE_11W
8753 case WLAN_CIPHER_SUITE_AES_CMAC:
8754 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07008755 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07008756#endif
8757
Jeff Johnson295189b2012-06-20 16:38:30 -07008758 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008759 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07008760 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308761 status = -EOPNOTSUPP;
8762 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008763 }
8764
8765 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
8766 __func__, setKey.encType);
8767
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008768 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07008769#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8770 (!pairwise)
8771#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008772 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07008773#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008774 )
8775 {
8776 /* set group key*/
8777 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8778 "%s- %d: setting Broadcast key",
8779 __func__, __LINE__);
8780 setKey.keyDirection = eSIR_RX_ONLY;
8781 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8782 }
8783 else
8784 {
8785 /* set pairwise key*/
8786 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8787 "%s- %d: setting pairwise key",
8788 __func__, __LINE__);
8789 setKey.keyDirection = eSIR_TX_RX;
8790 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8791 }
8792 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
8793 {
8794 setKey.keyDirection = eSIR_TX_RX;
8795 /*Set the group key*/
8796 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8797 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07008798
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008799 if ( 0 != status )
8800 {
8801 hddLog(VOS_TRACE_LEVEL_ERROR,
8802 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308803 status = -EINVAL;
8804 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008805 }
8806 /*Save the keys here and call sme_RoamSetKey for setting
8807 the PTK after peer joins the IBSS network*/
8808 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
8809 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308810 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008811 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05308812 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
8813 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
8814 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008815 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008816 if( pHostapdState->bssState == BSS_START )
8817 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008818 status = WLANSAP_SetKeySta( pVosContext, &setKey);
8819
8820 if ( status != eHAL_STATUS_SUCCESS )
8821 {
8822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8823 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8824 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308825 status = -EINVAL;
8826 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008827 }
8828 }
8829
8830 /* Saving WEP keys */
8831 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
8832 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
8833 {
8834 //Save the wep key in ap context. Issue setkey after the BSS is started.
8835 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8836 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
8837 }
8838 else
8839 {
8840 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008841 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008842 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
8843 }
8844 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008845 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
8846 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008847 {
8848 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8849 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8850
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308851#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8852 if (!pairwise)
8853#else
8854 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8855#endif
8856 {
8857 /* set group key*/
8858 if (pHddStaCtx->roam_info.deferKeyComplete)
8859 {
8860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8861 "%s- %d: Perform Set key Complete",
8862 __func__, __LINE__);
8863 hdd_PerformRoamSetKeyComplete(pAdapter);
8864 }
8865 }
8866
Jeff Johnson295189b2012-06-20 16:38:30 -07008867 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
8868
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08008869 pWextState->roamProfile.Keys.defaultIndex = key_index;
8870
8871
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008872 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008873 params->key, params->key_len);
8874
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308875
Jeff Johnson295189b2012-06-20 16:38:30 -07008876 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8877
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308878 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008879 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308880 __func__, setKey.peerMac[0], setKey.peerMac[1],
8881 setKey.peerMac[2], setKey.peerMac[3],
8882 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008883 setKey.keyDirection);
8884
Nirav Shah4f765af2015-01-21 19:51:30 +05308885 /* Wait for EAPOL M4 before setting key.
8886 * No need to consider Dynamic WEP as we will receive M8.
8887 */
8888 if ( (setKey.encType == eCSR_ENCRYPT_TYPE_AES ||
8889 setKey.encType == eCSR_ENCRYPT_TYPE_TKIP) &&
8890 ( 1
8891#if defined WLAN_FEATURE_VOWIFI_11R
8892 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN
8893 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN_PSK
8894#endif
8895#ifdef FEATURE_WLAN_ESE
8896 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_WPA
8897 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_RSN
8898#endif
8899 ))
Jeff Johnson295189b2012-06-20 16:38:30 -07008900 {
Nirav Shah4f765af2015-01-21 19:51:30 +05308901 vos_status = wlan_hdd_check_ula_done(pAdapter);
8902
8903 if ( vos_status != VOS_STATUS_SUCCESS )
8904 {
8905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008906 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8907 __LINE__, vos_status );
8908
Nirav Shah4f765af2015-01-21 19:51:30 +05308909 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008910
Nirav Shah4f765af2015-01-21 19:51:30 +05308911 status = -EINVAL;
8912 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008913
Nirav Shah4f765af2015-01-21 19:51:30 +05308914 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008915 }
8916
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008917#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308918 /* The supplicant may attempt to set the PTK once pre-authentication
8919 is done. Save the key in the UMAC and include it in the ADD BSS
8920 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008921 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308922 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008923 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308924 hddLog(VOS_TRACE_LEVEL_INFO_MED,
8925 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308926 status = 0;
8927 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308928 }
8929 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
8930 {
8931 hddLog(VOS_TRACE_LEVEL_ERROR,
8932 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308933 status = -EINVAL;
8934 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008935 }
8936#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07008937
8938 /* issue set key request to SME*/
8939 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8940 pAdapter->sessionId, &setKey, &roamId );
8941
8942 if ( 0 != status )
8943 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308944 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008945 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
8946 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308947 status = -EINVAL;
8948 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008949 }
8950
8951
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308952 /* in case of IBSS as there was no information available about WEP keys during
8953 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07008954 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308955 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
8956 !( ( IW_AUTH_KEY_MGMT_802_1X
8957 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07008958 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
8959 )
8960 &&
8961 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
8962 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
8963 )
8964 )
8965 {
8966 setKey.keyDirection = eSIR_RX_ONLY;
8967 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8968
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308969 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008970 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308971 __func__, setKey.peerMac[0], setKey.peerMac[1],
8972 setKey.peerMac[2], setKey.peerMac[3],
8973 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008974 setKey.keyDirection);
8975
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308976 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008977 pAdapter->sessionId, &setKey, &roamId );
8978
8979 if ( 0 != status )
8980 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308981 hddLog(VOS_TRACE_LEVEL_ERROR,
8982 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008983 __func__, status);
8984 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308985 status = -EINVAL;
8986 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008987 }
8988 }
8989 }
8990
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308991end:
8992 /* Need to clear any trace of key value in the memory.
8993 * Thus zero out the memory even though it is local
8994 * variable.
8995 */
8996 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308997 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308998 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008999}
9000
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309001#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9002static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9003 struct net_device *ndev,
9004 u8 key_index, bool pairwise,
9005 const u8 *mac_addr,
9006 struct key_params *params
9007 )
9008#else
9009static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9010 struct net_device *ndev,
9011 u8 key_index, const u8 *mac_addr,
9012 struct key_params *params
9013 )
9014#endif
9015{
9016 int ret;
9017 vos_ssr_protect(__func__);
9018#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9019 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
9020 mac_addr, params);
9021#else
9022 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
9023 params);
9024#endif
9025 vos_ssr_unprotect(__func__);
9026
9027 return ret;
9028}
9029
Jeff Johnson295189b2012-06-20 16:38:30 -07009030/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309031 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009032 * This function is used to get the key information
9033 */
9034#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309035static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309036 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009037 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309038 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009039 const u8 *mac_addr, void *cookie,
9040 void (*callback)(void *cookie, struct key_params*)
9041 )
9042#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309043static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309044 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009045 struct net_device *ndev,
9046 u8 key_index, const u8 *mac_addr, void *cookie,
9047 void (*callback)(void *cookie, struct key_params*)
9048 )
9049#endif
9050{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309051 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309052 hdd_wext_state_t *pWextState = NULL;
9053 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009054 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309055 hdd_context_t *pHddCtx;
9056 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009057
9058 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309059
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309060 if (NULL == pAdapter)
9061 {
9062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9063 "%s: HDD adapter is Null", __func__);
9064 return -ENODEV;
9065 }
9066
9067 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9068 ret = wlan_hdd_validate_context(pHddCtx);
9069 if (0 != ret)
9070 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309071 return ret;
9072 }
9073
9074 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9075 pRoamProfile = &(pWextState->roamProfile);
9076
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309077 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9078 __func__, hdd_device_modetoString(pAdapter->device_mode),
9079 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309080
Jeff Johnson295189b2012-06-20 16:38:30 -07009081 memset(&params, 0, sizeof(params));
9082
9083 if (CSR_MAX_NUM_KEY <= key_index)
9084 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07009086 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309087 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009088
9089 switch(pRoamProfile->EncryptionType.encryptionType[0])
9090 {
9091 case eCSR_ENCRYPT_TYPE_NONE:
9092 params.cipher = IW_AUTH_CIPHER_NONE;
9093 break;
9094
9095 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
9096 case eCSR_ENCRYPT_TYPE_WEP40:
9097 params.cipher = WLAN_CIPHER_SUITE_WEP40;
9098 break;
9099
9100 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
9101 case eCSR_ENCRYPT_TYPE_WEP104:
9102 params.cipher = WLAN_CIPHER_SUITE_WEP104;
9103 break;
9104
9105 case eCSR_ENCRYPT_TYPE_TKIP:
9106 params.cipher = WLAN_CIPHER_SUITE_TKIP;
9107 break;
9108
9109 case eCSR_ENCRYPT_TYPE_AES:
9110 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
9111 break;
9112
9113 default:
9114 params.cipher = IW_AUTH_CIPHER_NONE;
9115 break;
9116 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309117
c_hpothuaaf19692014-05-17 17:01:48 +05309118 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9119 TRACE_CODE_HDD_CFG80211_GET_KEY,
9120 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309121
Jeff Johnson295189b2012-06-20 16:38:30 -07009122 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
9123 params.seq_len = 0;
9124 params.seq = NULL;
9125 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
9126 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309127 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009128 return 0;
9129}
9130
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309131#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9132static int wlan_hdd_cfg80211_get_key(
9133 struct wiphy *wiphy,
9134 struct net_device *ndev,
9135 u8 key_index, bool pairwise,
9136 const u8 *mac_addr, void *cookie,
9137 void (*callback)(void *cookie, struct key_params*)
9138 )
9139#else
9140static int wlan_hdd_cfg80211_get_key(
9141 struct wiphy *wiphy,
9142 struct net_device *ndev,
9143 u8 key_index, const u8 *mac_addr, void *cookie,
9144 void (*callback)(void *cookie, struct key_params*)
9145 )
9146#endif
9147{
9148 int ret;
9149
9150 vos_ssr_protect(__func__);
9151#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9152 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
9153 mac_addr, cookie, callback);
9154#else
9155 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
9156 callback);
9157#endif
9158 vos_ssr_unprotect(__func__);
9159
9160 return ret;
9161}
9162
Jeff Johnson295189b2012-06-20 16:38:30 -07009163/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309164 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009165 * This function is used to delete the key information
9166 */
9167#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309168static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009169 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309170 u8 key_index,
9171 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009172 const u8 *mac_addr
9173 )
9174#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309175static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009176 struct net_device *ndev,
9177 u8 key_index,
9178 const u8 *mac_addr
9179 )
9180#endif
9181{
9182 int status = 0;
9183
9184 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309185 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009186 //it is observed that this is invalidating peer
9187 //key index whenever re-key is done. This is affecting data link.
9188 //It should be ok to ignore del_key.
9189#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309190 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
9191 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009192 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
9193 tCsrRoamSetKey setKey;
9194 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309195
Jeff Johnson295189b2012-06-20 16:38:30 -07009196 ENTER();
9197
9198 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
9199 __func__,pAdapter->device_mode);
9200
9201 if (CSR_MAX_NUM_KEY <= key_index)
9202 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309203 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009204 key_index);
9205
9206 return -EINVAL;
9207 }
9208
9209 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9210 setKey.keyId = key_index;
9211
9212 if (mac_addr)
9213 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9214 else
9215 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
9216
9217 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
9218
9219 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009220 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309221 )
9222 {
9223
9224 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07009225 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9226 if( pHostapdState->bssState == BSS_START)
9227 {
9228 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309229
Jeff Johnson295189b2012-06-20 16:38:30 -07009230 if ( status != eHAL_STATUS_SUCCESS )
9231 {
9232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9233 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9234 __LINE__, status );
9235 }
9236 }
9237 }
9238 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309239 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07009240 )
9241 {
9242 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9243
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309244 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9245
9246 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009247 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309248 __func__, setKey.peerMac[0], setKey.peerMac[1],
9249 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07009250 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309251 if(pAdapter->sessionCtx.station.conn_info.connState ==
9252 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07009253 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309254 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009255 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309256
Jeff Johnson295189b2012-06-20 16:38:30 -07009257 if ( 0 != status )
9258 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309259 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009260 "%s: sme_RoamSetKey failure, returned %d",
9261 __func__, status);
9262 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9263 return -EINVAL;
9264 }
9265 }
9266 }
9267#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009268 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009269 return status;
9270}
9271
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309272#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9273static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9274 struct net_device *ndev,
9275 u8 key_index,
9276 bool pairwise,
9277 const u8 *mac_addr
9278 )
9279#else
9280static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9281 struct net_device *ndev,
9282 u8 key_index,
9283 const u8 *mac_addr
9284 )
9285#endif
9286{
9287 int ret;
9288
9289 vos_ssr_protect(__func__);
9290#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9291 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
9292 mac_addr);
9293#else
9294 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
9295#endif
9296 vos_ssr_unprotect(__func__);
9297
9298 return ret;
9299}
9300
Jeff Johnson295189b2012-06-20 16:38:30 -07009301/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309302 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009303 * This function is used to set the default tx key index
9304 */
9305#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309306static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009307 struct net_device *ndev,
9308 u8 key_index,
9309 bool unicast, bool multicast)
9310#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309311static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009312 struct net_device *ndev,
9313 u8 key_index)
9314#endif
9315{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309316 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309317 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309318 hdd_wext_state_t *pWextState;
9319 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309320 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009321
9322 ENTER();
9323
Gopichand Nakkala29149562013-05-10 21:43:41 +05309324 if ((NULL == pAdapter))
9325 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309327 "invalid adapter");
9328 return -EINVAL;
9329 }
9330
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309331 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9332 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
9333 pAdapter->sessionId, key_index));
9334
Gopichand Nakkala29149562013-05-10 21:43:41 +05309335 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9336 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9337
9338 if ((NULL == pWextState) || (NULL == pHddStaCtx))
9339 {
9340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9341 "invalid Wext state or HDD context");
9342 return -EINVAL;
9343 }
9344
Arif Hussain6d2a3322013-11-17 19:50:10 -08009345 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009346 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309347
Jeff Johnson295189b2012-06-20 16:38:30 -07009348 if (CSR_MAX_NUM_KEY <= key_index)
9349 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309350 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009351 key_index);
9352
9353 return -EINVAL;
9354 }
9355
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309356 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9357 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309358 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009359 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309360 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009361 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309362
Jeff Johnson295189b2012-06-20 16:38:30 -07009363 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07009364 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309365 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009366 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309367 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08009368 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309369 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08009370 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07009371 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309372 {
9373 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07009374 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309375
Jeff Johnson295189b2012-06-20 16:38:30 -07009376 tCsrRoamSetKey setKey;
9377 v_U32_t roamId= 0xFF;
9378 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309379
9380 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009381 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309382
Jeff Johnson295189b2012-06-20 16:38:30 -07009383 Keys->defaultIndex = (u8)key_index;
9384 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9385 setKey.keyId = key_index;
9386 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309387
9388 vos_mem_copy(&setKey.Key[0],
9389 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009390 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309391
Gopichand Nakkala29149562013-05-10 21:43:41 +05309392 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309393
9394 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07009395 &pHddStaCtx->conn_info.bssId[0],
9396 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309397
Gopichand Nakkala29149562013-05-10 21:43:41 +05309398 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
9399 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
9400 eCSR_ENCRYPT_TYPE_WEP104)
9401 {
9402 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
9403 even though ap is configured for WEP-40 encryption. In this canse the key length
9404 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
9405 type(104) and switching encryption type to 40*/
9406 pWextState->roamProfile.EncryptionType.encryptionType[0] =
9407 eCSR_ENCRYPT_TYPE_WEP40;
9408 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
9409 eCSR_ENCRYPT_TYPE_WEP40;
9410 }
9411
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309412 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07009413 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309414
Jeff Johnson295189b2012-06-20 16:38:30 -07009415 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309416 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009417 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309418
Jeff Johnson295189b2012-06-20 16:38:30 -07009419 if ( 0 != status )
9420 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309421 hddLog(VOS_TRACE_LEVEL_ERROR,
9422 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009423 status);
9424 return -EINVAL;
9425 }
9426 }
9427 }
9428
9429 /* In SoftAp mode setting key direction for default mode */
9430 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
9431 {
9432 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
9433 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
9434 (eCSR_ENCRYPT_TYPE_AES !=
9435 pWextState->roamProfile.EncryptionType.encryptionType[0])
9436 )
9437 {
9438 /* Saving key direction for default key index to TX default */
9439 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9440 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
9441 }
9442 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309443 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009444 return status;
9445}
9446
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309447#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9448static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9449 struct net_device *ndev,
9450 u8 key_index,
9451 bool unicast, bool multicast)
9452#else
9453static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9454 struct net_device *ndev,
9455 u8 key_index)
9456#endif
9457{
9458 int ret;
9459 vos_ssr_protect(__func__);
9460#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9461 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
9462 multicast);
9463#else
9464 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
9465#endif
9466 vos_ssr_unprotect(__func__);
9467
9468 return ret;
9469}
9470
Jeff Johnson295189b2012-06-20 16:38:30 -07009471/*
9472 * FUNCTION: wlan_hdd_cfg80211_inform_bss
9473 * This function is used to inform the BSS details to nl80211 interface.
9474 */
9475static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
9476 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
9477{
9478 struct net_device *dev = pAdapter->dev;
9479 struct wireless_dev *wdev = dev->ieee80211_ptr;
9480 struct wiphy *wiphy = wdev->wiphy;
9481 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
9482 int chan_no;
9483 int ie_length;
9484 const char *ie;
9485 unsigned int freq;
9486 struct ieee80211_channel *chan;
9487 int rssi = 0;
9488 struct cfg80211_bss *bss = NULL;
9489
9490 ENTER();
9491
9492 if( NULL == pBssDesc )
9493 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009494 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009495 return bss;
9496 }
9497
9498 chan_no = pBssDesc->channelId;
9499 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
9500 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
9501
9502 if( NULL == ie )
9503 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009504 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009505 return bss;
9506 }
9507
9508#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9509 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9510 {
9511 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9512 }
9513 else
9514 {
9515 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9516 }
9517#else
9518 freq = ieee80211_channel_to_frequency(chan_no);
9519#endif
9520
9521 chan = __ieee80211_get_channel(wiphy, freq);
9522
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05309523 if (!chan) {
9524 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
9525 return NULL;
9526 }
9527
Abhishek Singhaee43942014-06-16 18:55:47 +05309528 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07009529
Abhishek Singhaee43942014-06-16 18:55:47 +05309530 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309531 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07009532 pBssDesc->capabilityInfo,
9533 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05309534 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07009535}
9536
9537
9538
9539/*
9540 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
9541 * This function is used to inform the BSS details to nl80211 interface.
9542 */
9543struct cfg80211_bss*
9544wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9545 tSirBssDescription *bss_desc
9546 )
9547{
9548 /*
9549 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9550 already exists in bss data base of cfg80211 for that particular BSS ID.
9551 Using cfg80211_inform_bss_frame to update the bss entry instead of
9552 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9553 now there is no possibility to get the mgmt(probe response) frame from PE,
9554 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9555 cfg80211_inform_bss_frame.
9556 */
9557 struct net_device *dev = pAdapter->dev;
9558 struct wireless_dev *wdev = dev->ieee80211_ptr;
9559 struct wiphy *wiphy = wdev->wiphy;
9560 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009561#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9562 qcom_ie_age *qie_age = NULL;
9563 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9564#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009565 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009566#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009567 const char *ie =
9568 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9569 unsigned int freq;
9570 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309571 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009572 struct cfg80211_bss *bss_status = NULL;
9573 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9574 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009575 hdd_context_t *pHddCtx;
9576 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009577#ifdef WLAN_OPEN_SOURCE
9578 struct timespec ts;
9579#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009580
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309581 ENTER();
9582
Wilson Yangf80a0542013-10-07 13:02:37 -07009583 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9584 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -07009585 if (0 != status)
9586 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009587 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009588 }
9589
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309590 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009591 if (!mgmt)
9592 {
9593 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9594 "%s: memory allocation failed ", __func__);
9595 return NULL;
9596 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009597
Jeff Johnson295189b2012-06-20 16:38:30 -07009598 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07009599
9600#ifdef WLAN_OPEN_SOURCE
9601 /* Android does not want the timestamp from the frame.
9602 Instead it wants a monotonic increasing value */
9603 get_monotonic_boottime(&ts);
9604 mgmt->u.probe_resp.timestamp =
9605 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
9606#else
9607 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009608 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
9609 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07009610
9611#endif
9612
Jeff Johnson295189b2012-06-20 16:38:30 -07009613 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
9614 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009615
9616#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9617 /* GPS Requirement: need age ie per entry. Using vendor specific. */
9618 /* Assuming this is the last IE, copy at the end */
9619 ie_length -=sizeof(qcom_ie_age);
9620 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
9621 qie_age->element_id = QCOM_VENDOR_IE_ID;
9622 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
9623 qie_age->oui_1 = QCOM_OUI1;
9624 qie_age->oui_2 = QCOM_OUI2;
9625 qie_age->oui_3 = QCOM_OUI3;
9626 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
9627 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
9628#endif
9629
Jeff Johnson295189b2012-06-20 16:38:30 -07009630 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05309631 if (bss_desc->fProbeRsp)
9632 {
9633 mgmt->frame_control |=
9634 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
9635 }
9636 else
9637 {
9638 mgmt->frame_control |=
9639 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
9640 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009641
9642#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309643 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009644 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
9645 {
9646 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9647 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309648 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009649 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
9650
9651 {
9652 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9653 }
9654 else
9655 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309656 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
9657 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07009658 kfree(mgmt);
9659 return NULL;
9660 }
9661#else
9662 freq = ieee80211_channel_to_frequency(chan_no);
9663#endif
9664 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009665 /*when the band is changed on the fly using the GUI, three things are done
9666 * 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)
9667 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
9668 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
9669 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
9670 * and discards the channels correponding to previous band and calls back with zero bss results.
9671 * 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
9672 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
9673 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
9674 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
9675 * So drop the bss and continue to next bss.
9676 */
9677 if(chan == NULL)
9678 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309679 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07009680 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009681 return NULL;
9682 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009683 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309684 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07009685 * */
9686 if (( eConnectionState_Associated ==
9687 pAdapter->sessionCtx.station.conn_info.connState ) &&
9688 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
9689 pAdapter->sessionCtx.station.conn_info.bssId,
9690 WNI_CFG_BSSID_LEN)))
9691 {
9692 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
9693 rssi = (pAdapter->rssi * 100);
9694 }
9695 else
9696 {
9697 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
9698 }
9699
Nirav Shah20ac06f2013-12-12 18:14:06 +05309700 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
9701 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
9702 chan->center_freq, (int)(rssi/100));
9703
Jeff Johnson295189b2012-06-20 16:38:30 -07009704 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
9705 frame_len, rssi, GFP_KERNEL);
9706 kfree(mgmt);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309707 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009708 return bss_status;
9709}
9710
9711/*
9712 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
9713 * This function is used to update the BSS data base of CFG8011
9714 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309715struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009716 tCsrRoamInfo *pRoamInfo
9717 )
9718{
9719 tCsrRoamConnectedProfile roamProfile;
9720 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9721 struct cfg80211_bss *bss = NULL;
9722
9723 ENTER();
9724
9725 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
9726 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
9727
9728 if (NULL != roamProfile.pBssDesc)
9729 {
Girish Gowlif4b68022014-08-28 23:18:57 +05309730 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9731 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009732
9733 if (NULL == bss)
9734 {
9735 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
9736 __func__);
9737 }
9738
9739 sme_RoamFreeConnectProfile(hHal, &roamProfile);
9740 }
9741 else
9742 {
9743 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
9744 __func__);
9745 }
9746 return bss;
9747}
9748
9749/*
9750 * FUNCTION: wlan_hdd_cfg80211_update_bss
9751 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309752static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
9753 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07009754 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309755{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309756 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009757 tCsrScanResultInfo *pScanResult;
9758 eHalStatus status = 0;
9759 tScanResultHandle pResult;
9760 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009761 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009762
9763 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309764
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309765 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9766 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
9767 NO_SESSION, pAdapter->sessionId));
9768
Wilson Yangf80a0542013-10-07 13:02:37 -07009769 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9770
9771 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009772 {
Wilson Yangf80a0542013-10-07 13:02:37 -07009773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9774 "%s:LOGP in Progress. Ignore!!!",__func__);
9775 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009776 }
9777
Wilson Yangf80a0542013-10-07 13:02:37 -07009778
9779 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309780 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009781 {
9782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9783 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9784 return VOS_STATUS_E_PERM;
9785 }
9786
9787
Jeff Johnson295189b2012-06-20 16:38:30 -07009788 /*
9789 * start getting scan results and populate cgf80211 BSS database
9790 */
9791 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
9792
9793 /* no scan results */
9794 if (NULL == pResult)
9795 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309796 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
9797 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009798 return status;
9799 }
9800
9801 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
9802
9803 while (pScanResult)
9804 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309805 /*
9806 * cfg80211_inform_bss() is not updating ie field of bss entry, if
9807 * entry already exists in bss data base of cfg80211 for that
9808 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
9809 * bss entry instead of cfg80211_inform_bss, But this call expects
9810 * mgmt packet as input. As of now there is no possibility to get
9811 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07009812 * ieee80211_mgmt(probe response) and passing to c
9813 * fg80211_inform_bss_frame.
9814 * */
9815
9816 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9817 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309818
Jeff Johnson295189b2012-06-20 16:38:30 -07009819
9820 if (NULL == bss_status)
9821 {
9822 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009823 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009824 }
9825 else
9826 {
Yue Maf49ba872013-08-19 12:04:25 -07009827 cfg80211_put_bss(
9828#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
9829 wiphy,
9830#endif
9831 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009832 }
9833
9834 pScanResult = sme_ScanResultGetNext(hHal, pResult);
9835 }
9836
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309837 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07009838
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309839 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009840}
9841
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009842void
9843hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
9844{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309845 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08009846 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009847} /****** end hddPrintMacAddr() ******/
9848
9849void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009850hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009851{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309852 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009853 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009854 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
9855 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
9856 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009857} /****** end hddPrintPmkId() ******/
9858
9859//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
9860//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
9861
9862//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
9863//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
9864
9865#define dump_bssid(bssid) \
9866 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009867 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
9868 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009869 }
9870
9871#define dump_pmkid(pMac, pmkid) \
9872 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009873 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
9874 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009875 }
9876
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009877#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009878/*
9879 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
9880 * This function is used to notify the supplicant of a new PMKSA candidate.
9881 */
9882int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309883 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009884 int index, bool preauth )
9885{
Jeff Johnsone7245742012-09-05 17:12:55 -07009886#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009887 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009888 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009889
9890 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07009891 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009892
9893 if( NULL == pRoamInfo )
9894 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009895 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009896 return -EINVAL;
9897 }
9898
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009899 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
9900 {
9901 dump_bssid(pRoamInfo->bssid);
9902 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009903 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009904 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009905#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309906 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009907}
9908#endif //FEATURE_WLAN_LFR
9909
Yue Maef608272013-04-08 23:09:17 -07009910#ifdef FEATURE_WLAN_LFR_METRICS
9911/*
9912 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
9913 * 802.11r/LFR metrics reporting function to report preauth initiation
9914 *
9915 */
9916#define MAX_LFR_METRICS_EVENT_LENGTH 100
9917VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
9918 tCsrRoamInfo *pRoamInfo)
9919{
9920 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9921 union iwreq_data wrqu;
9922
9923 ENTER();
9924
9925 if (NULL == pAdapter)
9926 {
9927 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9928 return VOS_STATUS_E_FAILURE;
9929 }
9930
9931 /* create the event */
9932 memset(&wrqu, 0, sizeof(wrqu));
9933 memset(metrics_notification, 0, sizeof(metrics_notification));
9934
9935 wrqu.data.pointer = metrics_notification;
9936 wrqu.data.length = scnprintf(metrics_notification,
9937 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
9938 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9939
9940 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9941
9942 EXIT();
9943
9944 return VOS_STATUS_SUCCESS;
9945}
9946
9947/*
9948 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
9949 * 802.11r/LFR metrics reporting function to report preauth completion
9950 * or failure
9951 */
9952VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
9953 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
9954{
9955 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9956 union iwreq_data wrqu;
9957
9958 ENTER();
9959
9960 if (NULL == pAdapter)
9961 {
9962 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9963 return VOS_STATUS_E_FAILURE;
9964 }
9965
9966 /* create the event */
9967 memset(&wrqu, 0, sizeof(wrqu));
9968 memset(metrics_notification, 0, sizeof(metrics_notification));
9969
9970 scnprintf(metrics_notification, sizeof(metrics_notification),
9971 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
9972 MAC_ADDR_ARRAY(pRoamInfo->bssid));
9973
9974 if (1 == preauth_status)
9975 strncat(metrics_notification, " TRUE", 5);
9976 else
9977 strncat(metrics_notification, " FALSE", 6);
9978
9979 wrqu.data.pointer = metrics_notification;
9980 wrqu.data.length = strlen(metrics_notification);
9981
9982 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9983
9984 EXIT();
9985
9986 return VOS_STATUS_SUCCESS;
9987}
9988
9989/*
9990 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
9991 * 802.11r/LFR metrics reporting function to report handover initiation
9992 *
9993 */
9994VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
9995 tCsrRoamInfo *pRoamInfo)
9996{
9997 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9998 union iwreq_data wrqu;
9999
10000 ENTER();
10001
10002 if (NULL == pAdapter)
10003 {
10004 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10005 return VOS_STATUS_E_FAILURE;
10006 }
10007
10008 /* create the event */
10009 memset(&wrqu, 0, sizeof(wrqu));
10010 memset(metrics_notification, 0, sizeof(metrics_notification));
10011
10012 wrqu.data.pointer = metrics_notification;
10013 wrqu.data.length = scnprintf(metrics_notification,
10014 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
10015 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10016
10017 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10018
10019 EXIT();
10020
10021 return VOS_STATUS_SUCCESS;
10022}
10023#endif
10024
Jeff Johnson295189b2012-06-20 16:38:30 -070010025/*
10026 * FUNCTION: hdd_cfg80211_scan_done_callback
10027 * scanning callback function, called after finishing scan
10028 *
10029 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010030static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070010031 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
10032{
10033 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010034 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070010035 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010036 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010037 struct cfg80211_scan_request *req = NULL;
10038 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010039 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010040 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010041 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010042 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010043
10044 ENTER();
10045
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010046 if (!pAdapter) {
10047 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
10048 goto allow_suspend;
10049 }
10050
10051 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10052 if (0 != wlan_hdd_validate_context(pHddCtx)) {
10053 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
10054 goto allow_suspend;
10055 }
10056
10057 pScanInfo = &pHddCtx->scan_info;
10058
Jeff Johnson295189b2012-06-20 16:38:30 -070010059 hddLog(VOS_TRACE_LEVEL_INFO,
10060 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080010061 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010062 __func__, halHandle, pContext, (int) scanId, (int) status);
10063
Kiet Lamac06e2c2013-10-23 16:25:07 +053010064 pScanInfo->mScanPendingCounter = 0;
10065
Jeff Johnson295189b2012-06-20 16:38:30 -070010066 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010067 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010068 &pScanInfo->scan_req_completion_event,
10069 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010070 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070010071 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010072 hddLog(VOS_TRACE_LEVEL_ERROR,
10073 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070010074 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010075 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010076 }
10077
Yue Maef608272013-04-08 23:09:17 -070010078 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010079 {
10080 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010081 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010082 }
10083
10084 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010085 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070010086 {
10087 hddLog(VOS_TRACE_LEVEL_INFO,
10088 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010089 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070010090 (int) scanId);
10091 }
10092
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010093 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010094 pAdapter);
10095
10096 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010097 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010098
10099
10100 /* If any client wait scan result through WEXT
10101 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010102 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070010103 {
10104 /* The other scan request waiting for current scan finish
10105 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010106 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010107 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010108 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070010109 }
10110 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010111 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010112 {
10113 struct net_device *dev = pAdapter->dev;
10114 union iwreq_data wrqu;
10115 int we_event;
10116 char *msg;
10117
10118 memset(&wrqu, '\0', sizeof(wrqu));
10119 we_event = SIOCGIWSCAN;
10120 msg = NULL;
10121 wireless_send_event(dev, we_event, &wrqu, msg);
10122 }
10123 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010124 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010125
10126 /* Get the Scan Req */
10127 req = pAdapter->request;
10128
10129 if (!req)
10130 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010131 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010132 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010133 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010134 }
10135
Jeff Johnson295189b2012-06-20 16:38:30 -070010136 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070010137 /* Scan is no longer pending */
10138 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010139
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010140 /* last_scan_timestamp is used to decide if new scan
10141 * is needed or not on station interface. If last station
10142 * scan time and new station scan time is less then
10143 * last_scan_timestamp ; driver will return cached scan.
10144 */
10145 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
10146 {
10147 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
10148
10149 if ( req->n_channels )
10150 {
10151 for (i = 0; i < req->n_channels ; i++ )
10152 {
10153 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
10154 }
10155 /* store no of channel scanned */
10156 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
10157 }
10158
10159 }
10160
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070010161 /*
10162 * cfg80211_scan_done informing NL80211 about completion
10163 * of scanning
10164 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010165 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
10166 {
10167 aborted = true;
10168 }
10169 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080010170 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010171
Siddharth Bhal76972212014-10-15 16:22:51 +053010172 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
10173 /* Generate new random mac addr for next scan */
10174 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
10175 hdd_processSpoofMacAddrRequest(pHddCtx);
10176 }
10177
Jeff Johnsone7245742012-09-05 17:12:55 -070010178allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010179 /* release the wake lock at the end of the scan*/
10180 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -070010181
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010182 /* Acquire wakelock to handle the case where APP's tries to suspend
10183 * immediatly after the driver gets connect request(i.e after scan)
10184 * from supplicant, this result in app's is suspending and not able
10185 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010186 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010187
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010188#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010189 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010190#endif
10191
Jeff Johnson295189b2012-06-20 16:38:30 -070010192 EXIT();
10193 return 0;
10194}
10195
10196/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053010197 * FUNCTION: hdd_isConnectionInProgress
10198 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010199 *
10200 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010201v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010202{
10203 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10204 hdd_station_ctx_t *pHddStaCtx = NULL;
10205 hdd_adapter_t *pAdapter = NULL;
10206 VOS_STATUS status = 0;
10207 v_U8_t staId = 0;
10208 v_U8_t *staMac = NULL;
10209
c_hpothu9b781ba2013-12-30 20:57:45 +053010210 if (TRUE == pHddCtx->btCoexModeSet)
10211 {
10212 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053010213 FL("BTCoex Mode operation in progress"));
10214 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053010215 }
10216
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010217 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10218
10219 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10220 {
10221 pAdapter = pAdapterNode->pAdapter;
10222
10223 if( pAdapter )
10224 {
10225 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010226 "%s: Adapter with device mode %s (%d) exists",
10227 __func__, hdd_device_modetoString(pAdapter->device_mode),
10228 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010229 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053010230 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10231 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
10232 (eConnectionState_Connecting ==
10233 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
10234 {
10235 hddLog(VOS_TRACE_LEVEL_ERROR,
10236 "%s: %p(%d) Connection is in progress", __func__,
10237 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10238 return VOS_TRUE;
10239 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010240 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053010241 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010242 {
10243 hddLog(VOS_TRACE_LEVEL_ERROR,
10244 "%s: %p(%d) Reassociation is in progress", __func__,
10245 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10246 return VOS_TRUE;
10247 }
10248 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010249 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10250 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010251 {
10252 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10253 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010254 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010255 {
10256 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
10257 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010258 "%s: client " MAC_ADDRESS_STR
10259 " is in the middle of WPS/EAPOL exchange.", __func__,
10260 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010261 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010262 }
10263 }
10264 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
10265 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
10266 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010267 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10268 ptSapContext pSapCtx = NULL;
10269 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10270 if(pSapCtx == NULL){
10271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10272 FL("psapCtx is NULL"));
10273 return VOS_FALSE;
10274 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010275 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
10276 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010277 if ((pSapCtx->aStaInfo[staId].isUsed) &&
10278 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010279 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010280 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010281
10282 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010283 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
10284 "middle of WPS/EAPOL exchange.", __func__,
10285 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010286 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010287 }
10288 }
10289 }
10290 }
10291 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10292 pAdapterNode = pNext;
10293 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053010294 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010295}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010296
10297/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010298 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070010299 * this scan respond to scan trigger and update cfg80211 scan database
10300 * later, scan dump command can be used to recieve scan results
10301 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010302int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010303#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10304 struct net_device *dev,
10305#endif
10306 struct cfg80211_scan_request *request)
10307{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010308 hdd_adapter_t *pAdapter = NULL;
10309 hdd_context_t *pHddCtx = NULL;
10310 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010311 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010312 tCsrScanRequest scanRequest;
10313 tANI_U8 *channelList = NULL, i;
10314 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010315 int status;
10316 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010317 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010318 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010319
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010320#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
10321 struct net_device *dev = NULL;
10322 if (NULL == request)
10323 {
10324 hddLog(VOS_TRACE_LEVEL_ERROR,
10325 "%s: scan req param null", __func__);
10326 return -EINVAL;
10327 }
10328 dev = request->wdev->netdev;
10329#endif
10330
10331 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
10332 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
10333 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10334
Jeff Johnson295189b2012-06-20 16:38:30 -070010335 ENTER();
10336
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010337 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10338 __func__, hdd_device_modetoString(pAdapter->device_mode),
10339 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010340
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010341 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010342 if (0 != status)
10343 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010344 return status;
10345 }
10346
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010347 if (NULL == pwextBuf)
10348 {
10349 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
10350 __func__);
10351 return -EIO;
10352 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010353 cfg_param = pHddCtx->cfg_ini;
10354 pScanInfo = &pHddCtx->scan_info;
10355
Jeff Johnson295189b2012-06-20 16:38:30 -070010356#ifdef WLAN_BTAMP_FEATURE
10357 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010358 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070010359 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010360 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010361 "%s: No scanning when AMP is on", __func__);
10362 return -EOPNOTSUPP;
10363 }
10364#endif
10365 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010366 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010367 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010368 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010369 "%s: Not scanning on device_mode = %s (%d)",
10370 __func__, hdd_device_modetoString(pAdapter->device_mode),
10371 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010372 return -EOPNOTSUPP;
10373 }
10374
10375 if (TRUE == pScanInfo->mScanPending)
10376 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010377 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
10378 {
10379 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
10380 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010381 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010382 }
10383
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010384 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070010385 //Channel and action frame is pending
10386 //Otherwise Cancel Remain On Channel and allow Scan
10387 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010388 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070010389 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010390 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010391 return -EBUSY;
10392 }
10393
Jeff Johnson295189b2012-06-20 16:38:30 -070010394 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
10395 {
10396 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080010397 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010398 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010399 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010400 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
10401 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010402 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010403 "%s: MAX TM Level Scan not allowed", __func__);
10404 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010405 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010406 }
10407 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
10408
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010409 /* Check if scan is allowed at this point of time.
10410 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010411 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010412 {
10413 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
10414 return -EBUSY;
10415 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010416
Jeff Johnson295189b2012-06-20 16:38:30 -070010417 vos_mem_zero( &scanRequest, sizeof(scanRequest));
10418
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010419 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
10420 (int)request->n_ssids);
10421
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010422
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010423 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
10424 * Becasue of this, driver is assuming that this is not wildcard scan and so
10425 * is not aging out the scan results.
10426 */
10427 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010428 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010429 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010430 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010431
10432 if ((request->ssids) && (0 < request->n_ssids))
10433 {
10434 tCsrSSIDInfo *SsidInfo;
10435 int j;
10436 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
10437 /* Allocate num_ssid tCsrSSIDInfo structure */
10438 SsidInfo = scanRequest.SSIDs.SSIDList =
10439 ( tCsrSSIDInfo *)vos_mem_malloc(
10440 request->n_ssids*sizeof(tCsrSSIDInfo));
10441
10442 if(NULL == scanRequest.SSIDs.SSIDList)
10443 {
10444 hddLog(VOS_TRACE_LEVEL_ERROR,
10445 "%s: memory alloc failed SSIDInfo buffer", __func__);
10446 return -ENOMEM;
10447 }
10448
10449 /* copy all the ssid's and their length */
10450 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
10451 {
10452 /* get the ssid length */
10453 SsidInfo->SSID.length = request->ssids[j].ssid_len;
10454 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
10455 SsidInfo->SSID.length);
10456 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
10457 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
10458 j, SsidInfo->SSID.ssId);
10459 }
10460 /* set the scan type to active */
10461 scanRequest.scanType = eSIR_ACTIVE_SCAN;
10462 }
10463 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070010464 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010465 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10466 TRACE_CODE_HDD_CFG80211_SCAN,
10467 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070010468 /* set the scan type to active */
10469 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010470 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010471 else
10472 {
10473 /*Set the scan type to default type, in this case it is ACTIVE*/
10474 scanRequest.scanType = pScanInfo->scan_mode;
10475 }
10476 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
10477 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070010478
10479 /* set BSSType to default type */
10480 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
10481
10482 /*TODO: scan the requested channels only*/
10483
10484 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010485 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070010486 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010487 hddLog(VOS_TRACE_LEVEL_WARN,
10488 "No of Scan Channels exceeded limit: %d", request->n_channels);
10489 request->n_channels = MAX_CHANNEL;
10490 }
10491
10492 hddLog(VOS_TRACE_LEVEL_INFO,
10493 "No of Scan Channels: %d", request->n_channels);
10494
10495
10496 if( request->n_channels )
10497 {
10498 char chList [(request->n_channels*5)+1];
10499 int len;
10500 channelList = vos_mem_malloc( request->n_channels );
10501 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053010502 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010503 hddLog(VOS_TRACE_LEVEL_ERROR,
10504 "%s: memory alloc failed channelList", __func__);
10505 status = -ENOMEM;
10506 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053010507 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010508
10509 for( i = 0, len = 0; i < request->n_channels ; i++ )
10510 {
10511 channelList[i] = request->channels[i]->hw_value;
10512 len += snprintf(chList+len, 5, "%d ", channelList[i]);
10513 }
10514
Nirav Shah20ac06f2013-12-12 18:14:06 +053010515 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010516 "Channel-List: %s ", chList);
10517 }
c_hpothu53512302014-04-15 18:49:53 +053010518
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010519 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
10520 scanRequest.ChannelInfo.ChannelList = channelList;
10521
10522 /* set requestType to full scan */
10523 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10524
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010525 /* if there is back to back scan happening in driver with in
10526 * nDeferScanTimeInterval interval driver should defer new scan request
10527 * and should provide last cached scan results instead of new channel list.
10528 * This rule is not applicable if scan is p2p scan.
10529 * This condition will work only in case when last request no of channels
10530 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053010531 * This should be done only in connected state
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010532 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010533
Agarwal Ashish57e84372014-12-05 18:26:53 +053010534 if ((VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
10535 {
10536 if ( pScanInfo->last_scan_timestamp !=0 &&
10537 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10538 {
10539 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
10540 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
10541 vos_mem_compare(pScanInfo->last_scan_channelList,
10542 channelList, pScanInfo->last_scan_numChannels))
10543 {
10544 hddLog(VOS_TRACE_LEVEL_WARN,
10545 " New and old station scan time differ is less then %u",
10546 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10547
10548 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010549 pAdapter);
10550
Agarwal Ashish57e84372014-12-05 18:26:53 +053010551 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010552 "Return old cached scan as all channels and no of channels are same");
10553
Agarwal Ashish57e84372014-12-05 18:26:53 +053010554 if (0 > ret)
10555 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010556
Agarwal Ashish57e84372014-12-05 18:26:53 +053010557 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010558
10559 status = eHAL_STATUS_SUCCESS;
10560 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053010561 }
10562 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010563 }
10564
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010565 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10566 * search (Flush on both full scan and social scan but not on single
10567 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10568 */
10569
10570 /* Supplicant does single channel scan after 8-way handshake
10571 * and in that case driver shoudnt flush scan results. If
10572 * driver flushes the scan results here and unfortunately if
10573 * the AP doesnt respond to our probe req then association
10574 * fails which is not desired
10575 */
10576
10577 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
10578 {
10579 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
10580 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
10581 pAdapter->sessionId );
10582 }
10583
10584 if( request->ie_len )
10585 {
10586 /* save this for future association (join requires this) */
10587 /*TODO: Array needs to be converted to dynamic allocation,
10588 * as multiple ie.s can be sent in cfg80211_scan_request structure
10589 * CR 597966
10590 */
10591 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
10592 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
10593 pScanInfo->scanAddIE.length = request->ie_len;
10594
10595 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10596 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10597 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010598 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010599 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070010600 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010601 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
10602 memcpy( pwextBuf->roamProfile.addIEScan,
10603 request->ie, request->ie_len);
10604 }
10605 else
10606 {
10607 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
10608 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070010609 }
10610
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010611 }
10612 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
10613 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
10614
10615 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
10616 request->ie_len);
10617 if (pP2pIe != NULL)
10618 {
10619#ifdef WLAN_FEATURE_P2P_DEBUG
10620 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
10621 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
10622 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053010623 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010624 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
10625 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10626 "Go nego completed to Connection is started");
10627 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10628 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053010629 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010630 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
10631 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010632 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010633 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
10634 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10635 "Disconnected state to Connection is started");
10636 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10637 "for 4way Handshake");
10638 }
10639#endif
10640
10641 /* no_cck will be set during p2p find to disable 11b rates */
10642 if(TRUE == request->no_cck)
10643 {
10644 hddLog(VOS_TRACE_LEVEL_INFO,
10645 "%s: This is a P2P Search", __func__);
10646 scanRequest.p2pSearch = 1;
10647
10648 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053010649 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010650 /* set requestType to P2P Discovery */
10651 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
10652 }
10653
10654 /*
10655 Skip Dfs Channel in case of P2P Search
10656 if it is set in ini file
10657 */
10658 if(cfg_param->skipDfsChnlInP2pSearch)
10659 {
10660 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010661 }
10662 else
10663 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010664 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010665 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010666
Agarwal Ashish4f616132013-12-30 23:32:50 +053010667 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010668 }
10669 }
10670
10671 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
10672
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010673#ifdef FEATURE_WLAN_TDLS
10674 /* if tdls disagree scan right now, return immediately.
10675 tdls will schedule the scan when scan is allowed. (return SUCCESS)
10676 or will reject the scan if any TDLS is in progress. (return -EBUSY)
10677 */
10678 status = wlan_hdd_tdls_scan_callback (pAdapter,
10679 wiphy,
10680#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10681 dev,
10682#endif
10683 request);
10684 if(status <= 0)
10685 {
10686 if(!status)
10687 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
10688 "scan rejected %d", __func__, status);
10689 else
10690 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
10691 __func__, status);
10692
10693 return status;
10694 }
10695#endif
10696
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010697 /* acquire the wakelock to avoid the apps suspend during the scan. To
10698 * address the following issues.
10699 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
10700 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
10701 * for long time, this result in apps running at full power for long time.
10702 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
10703 * be stuck in full power because of resume BMPS
10704 */
10705 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -070010706
Nirav Shah20ac06f2013-12-12 18:14:06 +053010707 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10708 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010709 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
10710 scanRequest.requestType, scanRequest.scanType,
10711 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053010712 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
10713
Siddharth Bhal76972212014-10-15 16:22:51 +053010714 if (pHddCtx->spoofMacAddr.isEnabled)
10715 {
10716 hddLog(VOS_TRACE_LEVEL_INFO,
10717 "%s: MAC Spoofing enabled for current scan", __func__);
10718 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
10719 * to fill TxBds for probe request during current scan
10720 */
10721 WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
10722 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
10723 }
10724
Jeff Johnsone7245742012-09-05 17:12:55 -070010725 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010726 pAdapter->sessionId, &scanRequest, &scanId,
10727 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070010728
Jeff Johnson295189b2012-06-20 16:38:30 -070010729 if (eHAL_STATUS_SUCCESS != status)
10730 {
10731 hddLog(VOS_TRACE_LEVEL_ERROR,
10732 "%s: sme_ScanRequest returned error %d", __func__, status);
10733 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010734 if(eHAL_STATUS_RESOURCES == status)
10735 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010736 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
10737 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010738 status = -EBUSY;
10739 } else {
10740 status = -EIO;
10741 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010742 hdd_allow_suspend();
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010743
10744#ifdef FEATURE_WLAN_TDLS
10745 wlan_hdd_tdls_scan_done_callback(pAdapter);
10746#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010747 goto free_mem;
10748 }
10749
10750 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010751 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070010752 pAdapter->request = request;
10753 pScanInfo->scanId = scanId;
10754
10755 complete(&pScanInfo->scan_req_completion_event);
10756
10757free_mem:
10758 if( scanRequest.SSIDs.SSIDList )
10759 {
10760 vos_mem_free(scanRequest.SSIDs.SSIDList);
10761 }
10762
10763 if( channelList )
10764 vos_mem_free( channelList );
10765
10766 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010767 return status;
10768}
10769
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010770int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
10771#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10772 struct net_device *dev,
10773#endif
10774 struct cfg80211_scan_request *request)
10775{
10776 int ret;
10777
10778 vos_ssr_protect(__func__);
10779 ret = __wlan_hdd_cfg80211_scan(wiphy,
10780#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10781 dev,
10782#endif
10783 request);
10784 vos_ssr_unprotect(__func__);
10785
10786 return ret;
10787}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010788
10789void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
10790{
10791 v_U8_t iniDot11Mode =
10792 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
10793 eHddDot11Mode hddDot11Mode = iniDot11Mode;
10794
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010795 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
10796 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010797 switch ( iniDot11Mode )
10798 {
10799 case eHDD_DOT11_MODE_AUTO:
10800 case eHDD_DOT11_MODE_11ac:
10801 case eHDD_DOT11_MODE_11ac_ONLY:
10802#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053010803 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
10804 sme_IsFeatureSupportedByFW(DOT11AC) )
10805 hddDot11Mode = eHDD_DOT11_MODE_11ac;
10806 else
10807 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010808#else
10809 hddDot11Mode = eHDD_DOT11_MODE_11n;
10810#endif
10811 break;
10812 case eHDD_DOT11_MODE_11n:
10813 case eHDD_DOT11_MODE_11n_ONLY:
10814 hddDot11Mode = eHDD_DOT11_MODE_11n;
10815 break;
10816 default:
10817 hddDot11Mode = iniDot11Mode;
10818 break;
10819 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010820#ifdef WLAN_FEATURE_AP_HT40_24G
10821 if (operationChannel > SIR_11B_CHANNEL_END)
10822#endif
10823 {
10824 /* This call decides required channel bonding mode */
10825 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010826 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
10827 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010828 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010829}
10830
Jeff Johnson295189b2012-06-20 16:38:30 -070010831/*
10832 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010833 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010834 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010835int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010836 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010837{
10838 int status = 0;
10839 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080010840 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010841 v_U32_t roamId;
10842 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070010843 eCsrAuthType RSNAuthType;
10844
10845 ENTER();
10846
10847 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080010848 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10849
10850 status = wlan_hdd_validate_context(pHddCtx);
10851 if (status)
10852 {
Yue Mae36e3552014-03-05 17:06:20 -080010853 return status;
10854 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010855
Jeff Johnson295189b2012-06-20 16:38:30 -070010856 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
10857 {
10858 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
10859 return -EINVAL;
10860 }
10861
10862 pRoamProfile = &pWextState->roamProfile;
10863
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010864 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070010865 {
Jeff Johnsone7245742012-09-05 17:12:55 -070010866 hdd_station_ctx_t *pHddStaCtx;
10867 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010868
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010869 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070010870 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
10871 {
10872 /*QoS not enabled in cfg file*/
10873 pRoamProfile->uapsd_mask = 0;
10874 }
10875 else
10876 {
10877 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010878 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070010879 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
10880 }
10881
10882 pRoamProfile->SSIDs.numOfSSIDs = 1;
10883 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
10884 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010885 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070010886 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
10887 ssid, ssid_len);
10888
10889 if (bssid)
10890 {
10891 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
10892 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
10893 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010894 /* Save BSSID in seperate variable as well, as RoamProfile
10895 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070010896 case of join failure we should send valid BSSID to supplicant
10897 */
10898 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
10899 WNI_CFG_BSSID_LEN);
10900 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070010901 else
10902 {
10903 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
10904 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010905
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010906 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
10907 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010908 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
10909 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010910 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010911 /*set gen ie*/
10912 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
10913 /*set auth*/
10914 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
10915 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010916#ifdef FEATURE_WLAN_WAPI
10917 if (pAdapter->wapi_info.nWapiMode)
10918 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010919 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010920 switch (pAdapter->wapi_info.wapiAuthMode)
10921 {
10922 case WAPI_AUTH_MODE_PSK:
10923 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010924 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010925 pAdapter->wapi_info.wapiAuthMode);
10926 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
10927 break;
10928 }
10929 case WAPI_AUTH_MODE_CERT:
10930 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010931 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010932 pAdapter->wapi_info.wapiAuthMode);
10933 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
10934 break;
10935 }
10936 } // End of switch
10937 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
10938 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
10939 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010940 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010941 pRoamProfile->AuthType.numEntries = 1;
10942 pRoamProfile->EncryptionType.numEntries = 1;
10943 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10944 pRoamProfile->mcEncryptionType.numEntries = 1;
10945 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10946 }
10947 }
10948#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010949#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010950 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010951 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10952 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
10953 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010954 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
10955 sizeof (tSirGtkOffloadParams));
10956 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010957 }
10958#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010959 pRoamProfile->csrPersona = pAdapter->device_mode;
10960
Jeff Johnson32d95a32012-09-10 13:15:23 -070010961 if( operatingChannel )
10962 {
10963 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
10964 pRoamProfile->ChannelInfo.numOfChannels = 1;
10965 }
Chet Lanctot186b5732013-03-18 10:26:30 -070010966 else
10967 {
10968 pRoamProfile->ChannelInfo.ChannelList = NULL;
10969 pRoamProfile->ChannelInfo.numOfChannels = 0;
10970 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010971 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
10972 {
10973 hdd_select_cbmode(pAdapter,operatingChannel);
10974 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010975
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010976 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
10977 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010978 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010979 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010980 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
10981 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010982 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10983 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053010984 {
10985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10986 "%s: Set HDD connState to eConnectionState_Connecting",
10987 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010988 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
10989 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053010990 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010991 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010992 pAdapter->sessionId, pRoamProfile, &roamId);
10993
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010994 if ((eHAL_STATUS_SUCCESS != status) &&
10995 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10996 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010997
10998 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010999 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
11000 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
11001 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011002 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011003 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011004 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011005
11006 pRoamProfile->ChannelInfo.ChannelList = NULL;
11007 pRoamProfile->ChannelInfo.numOfChannels = 0;
11008
Jeff Johnson295189b2012-06-20 16:38:30 -070011009 }
11010 else
11011 {
11012 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
11013 return -EINVAL;
11014 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011015 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011016 return status;
11017}
11018
11019/*
11020 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
11021 * This function is used to set the authentication type (OPEN/SHARED).
11022 *
11023 */
11024static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
11025 enum nl80211_auth_type auth_type)
11026{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011027 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011028 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11029
11030 ENTER();
11031
11032 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011033 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070011034 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011035 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011036 hddLog(VOS_TRACE_LEVEL_INFO,
11037 "%s: set authentication type to AUTOSWITCH", __func__);
11038 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
11039 break;
11040
11041 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011042#ifdef WLAN_FEATURE_VOWIFI_11R
11043 case NL80211_AUTHTYPE_FT:
11044#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011045 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011046 "%s: set authentication type to OPEN", __func__);
11047 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11048 break;
11049
11050 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011051 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011052 "%s: set authentication type to SHARED", __func__);
11053 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
11054 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011055#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011056 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011057 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011058 "%s: set authentication type to CCKM WPA", __func__);
11059 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
11060 break;
11061#endif
11062
11063
11064 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011065 hddLog(VOS_TRACE_LEVEL_ERROR,
11066 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011067 auth_type);
11068 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
11069 return -EINVAL;
11070 }
11071
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011072 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011073 pHddStaCtx->conn_info.authType;
11074 return 0;
11075}
11076
11077/*
11078 * FUNCTION: wlan_hdd_set_akm_suite
11079 * This function is used to set the key mgmt type(PSK/8021x).
11080 *
11081 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011082static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011083 u32 key_mgmt
11084 )
11085{
11086 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11087 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053011088 /* Should be in ieee802_11_defs.h */
11089#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
11090#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070011091 /*set key mgmt type*/
11092 switch(key_mgmt)
11093 {
11094 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053011095 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011096#ifdef WLAN_FEATURE_VOWIFI_11R
11097 case WLAN_AKM_SUITE_FT_PSK:
11098#endif
11099 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070011100 __func__);
11101 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
11102 break;
11103
11104 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053011105 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011106#ifdef WLAN_FEATURE_VOWIFI_11R
11107 case WLAN_AKM_SUITE_FT_8021X:
11108#endif
11109 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070011110 __func__);
11111 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11112 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011113#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011114#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
11115#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
11116 case WLAN_AKM_SUITE_CCKM:
11117 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
11118 __func__);
11119 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
11120 break;
11121#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070011122#ifndef WLAN_AKM_SUITE_OSEN
11123#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
11124 case WLAN_AKM_SUITE_OSEN:
11125 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
11126 __func__);
11127 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11128 break;
11129#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011130
11131 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011132 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011133 __func__, key_mgmt);
11134 return -EINVAL;
11135
11136 }
11137 return 0;
11138}
11139
11140/*
11141 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011142 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070011143 * (NONE/WEP40/WEP104/TKIP/CCMP).
11144 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011145static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
11146 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070011147 bool ucast
11148 )
11149{
11150 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011151 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011152 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11153
11154 ENTER();
11155
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011156 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011157 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011158 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070011159 __func__, cipher);
11160 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11161 }
11162 else
11163 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011164
Jeff Johnson295189b2012-06-20 16:38:30 -070011165 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011166 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011167 {
11168 case IW_AUTH_CIPHER_NONE:
11169 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11170 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011171
Jeff Johnson295189b2012-06-20 16:38:30 -070011172 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011173 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070011174 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011175
Jeff Johnson295189b2012-06-20 16:38:30 -070011176 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011177 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070011178 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011179
Jeff Johnson295189b2012-06-20 16:38:30 -070011180 case WLAN_CIPHER_SUITE_TKIP:
11181 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
11182 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011183
Jeff Johnson295189b2012-06-20 16:38:30 -070011184 case WLAN_CIPHER_SUITE_CCMP:
11185 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11186 break;
11187#ifdef FEATURE_WLAN_WAPI
11188 case WLAN_CIPHER_SUITE_SMS4:
11189 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
11190 break;
11191#endif
11192
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011193#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011194 case WLAN_CIPHER_SUITE_KRK:
11195 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
11196 break;
11197#endif
11198 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011199 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011200 __func__, cipher);
11201 return -EOPNOTSUPP;
11202 }
11203 }
11204
11205 if (ucast)
11206 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011207 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011208 __func__, encryptionType);
11209 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11210 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011211 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011212 encryptionType;
11213 }
11214 else
11215 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011216 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011217 __func__, encryptionType);
11218 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
11219 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
11220 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
11221 }
11222
11223 return 0;
11224}
11225
11226
11227/*
11228 * FUNCTION: wlan_hdd_cfg80211_set_ie
11229 * This function is used to parse WPA/RSN IE's.
11230 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011231int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
11232 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070011233 size_t ie_len
11234 )
11235{
11236 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11237 u8 *genie = ie;
11238 v_U16_t remLen = ie_len;
11239#ifdef FEATURE_WLAN_WAPI
11240 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
11241 u16 *tmp;
11242 v_U16_t akmsuiteCount;
11243 int *akmlist;
11244#endif
11245 ENTER();
11246
11247 /* clear previous assocAddIE */
11248 pWextState->assocAddIE.length = 0;
11249 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011250 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011251
11252 while (remLen >= 2)
11253 {
11254 v_U16_t eLen = 0;
11255 v_U8_t elementId;
11256 elementId = *genie++;
11257 eLen = *genie++;
11258 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011259
Arif Hussain6d2a3322013-11-17 19:50:10 -080011260 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070011261 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011262
11263 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070011264 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011265 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011266 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 -070011267 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011268 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011269 "%s: Invalid WPA IE", __func__);
11270 return -EINVAL;
11271 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011272 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070011273 {
11274 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011275 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011276 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011277
Jeff Johnson295189b2012-06-20 16:38:30 -070011278 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11279 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011280 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
11281 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011282 VOS_ASSERT(0);
11283 return -ENOMEM;
11284 }
11285 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11286 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11287 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011288
Jeff Johnson295189b2012-06-20 16:38:30 -070011289 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
11290 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11291 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11292 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011293 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
11294 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011295 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
11296 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11297 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
11298 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
11299 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
11300 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011301 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053011302 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011303 {
11304 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011305 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011306 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011307
Jeff Johnson295189b2012-06-20 16:38:30 -070011308 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11309 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011310 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11311 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011312 VOS_ASSERT(0);
11313 return -ENOMEM;
11314 }
11315 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11316 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11317 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011318
Jeff Johnson295189b2012-06-20 16:38:30 -070011319 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11320 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11321 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011322#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011323 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
11324 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011325 /*Consider WFD IE, only for P2P Client */
11326 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11327 {
11328 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011329 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011330 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011331
Jeff Johnson295189b2012-06-20 16:38:30 -070011332 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11333 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011334 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11335 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011336 VOS_ASSERT(0);
11337 return -ENOMEM;
11338 }
11339 // WFD IE is saved to Additional IE ; it should be accumulated to handle
11340 // WPS IE + P2P IE + WFD IE
11341 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11342 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011343
Jeff Johnson295189b2012-06-20 16:38:30 -070011344 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11345 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11346 }
11347#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011348 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011349 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011350 HS20_OUI_TYPE_SIZE)) )
11351 {
11352 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011353 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011354 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011355
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011356 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11357 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011358 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11359 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011360 VOS_ASSERT(0);
11361 return -ENOMEM;
11362 }
11363 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11364 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011365
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011366 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11367 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11368 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011369 /* Appending OSEN Information Element in Assiciation Request */
11370 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
11371 OSEN_OUI_TYPE_SIZE)) )
11372 {
11373 v_U16_t curAddIELen = pWextState->assocAddIE.length;
11374 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
11375 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011376
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011377 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11378 {
11379 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11380 "Need bigger buffer space");
11381 VOS_ASSERT(0);
11382 return -ENOMEM;
11383 }
11384 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11385 pWextState->assocAddIE.length += eLen + 2;
11386
11387 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
11388 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11389 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11390 }
11391
11392 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011393 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
11394
11395 /* populating as ADDIE in beacon frames */
11396 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11397 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
11398 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
11399 {
11400 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11401 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
11402 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11403 {
11404 hddLog(LOGE,
11405 "Coldn't pass "
11406 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
11407 }
11408 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
11409 else
11410 hddLog(LOGE,
11411 "Could not pass on "
11412 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
11413
11414 /* IBSS mode doesn't contain params->proberesp_ies still
11415 beaconIE's need to be populated in probe response frames */
11416 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
11417 {
11418 u16 rem_probe_resp_ie_len = eLen + 2;
11419 u8 probe_rsp_ie_len[3] = {0};
11420 u8 counter = 0;
11421
11422 /* Check Probe Resp Length if it is greater then 255 then
11423 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
11424 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
11425 not able Store More then 255 bytes into One Variable */
11426
11427 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
11428 {
11429 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
11430 {
11431 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
11432 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
11433 }
11434 else
11435 {
11436 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
11437 rem_probe_resp_ie_len = 0;
11438 }
11439 }
11440
11441 rem_probe_resp_ie_len = 0;
11442
11443 if (probe_rsp_ie_len[0] > 0)
11444 {
11445 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11446 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
11447 (tANI_U8*)(genie - 2),
11448 probe_rsp_ie_len[0], NULL,
11449 eANI_BOOLEAN_FALSE)
11450 == eHAL_STATUS_FAILURE)
11451 {
11452 hddLog(LOGE,
11453 "Could not pass"
11454 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
11455 }
11456 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
11457 }
11458
11459 if (probe_rsp_ie_len[1] > 0)
11460 {
11461 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11462 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
11463 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11464 probe_rsp_ie_len[1], NULL,
11465 eANI_BOOLEAN_FALSE)
11466 == eHAL_STATUS_FAILURE)
11467 {
11468 hddLog(LOGE,
11469 "Could not pass"
11470 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
11471 }
11472 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
11473 }
11474
11475 if (probe_rsp_ie_len[2] > 0)
11476 {
11477 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11478 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
11479 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11480 probe_rsp_ie_len[2], NULL,
11481 eANI_BOOLEAN_FALSE)
11482 == eHAL_STATUS_FAILURE)
11483 {
11484 hddLog(LOGE,
11485 "Could not pass"
11486 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
11487 }
11488 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
11489 }
11490
11491 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11492 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
11493 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11494 {
11495 hddLog(LOGE,
11496 "Could not pass"
11497 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
11498 }
11499 }
11500 else
11501 {
11502 // Reset WNI_CFG_PROBE_RSP Flags
11503 wlan_hdd_reset_prob_rspies(pAdapter);
11504
11505 hddLog(VOS_TRACE_LEVEL_INFO,
11506 "%s: No Probe Response IE received in set beacon",
11507 __func__);
11508 }
11509 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011510 break;
11511 case DOT11F_EID_RSN:
11512 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11513 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11514 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11515 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11516 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11517 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011518 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
11519 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011520 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011521 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011522 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011523 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011524
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011525 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11526 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011527 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11528 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011529 VOS_ASSERT(0);
11530 return -ENOMEM;
11531 }
11532 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11533 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011534
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011535 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11536 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11537 break;
11538 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011539#ifdef FEATURE_WLAN_WAPI
11540 case WLAN_EID_WAPI:
11541 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011542 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011543 pAdapter->wapi_info.nWapiMode);
11544 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011545 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070011546 akmsuiteCount = WPA_GET_LE16(tmp);
11547 tmp = tmp + 1;
11548 akmlist = (int *)(tmp);
11549 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
11550 {
11551 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
11552 }
11553 else
11554 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011555 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070011556 VOS_ASSERT(0);
11557 return -EINVAL;
11558 }
11559
11560 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
11561 {
11562 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011563 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011564 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011565 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011566 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011567 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011568 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011569 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011570 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
11571 }
11572 break;
11573#endif
11574 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011575 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011576 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011577 /* when Unknown IE is received we should break and continue
11578 * to the next IE in the buffer instead we were returning
11579 * so changing this to break */
11580 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011581 }
11582 genie += eLen;
11583 remLen -= eLen;
11584 }
11585 EXIT();
11586 return 0;
11587}
11588
11589/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053011590 * FUNCTION: hdd_isWPAIEPresent
11591 * Parse the received IE to find the WPA IE
11592 *
11593 */
11594static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
11595{
11596 v_U8_t eLen = 0;
11597 v_U16_t remLen = ie_len;
11598 v_U8_t elementId = 0;
11599
11600 while (remLen >= 2)
11601 {
11602 elementId = *ie++;
11603 eLen = *ie++;
11604 remLen -= 2;
11605 if (eLen > remLen)
11606 {
11607 hddLog(VOS_TRACE_LEVEL_ERROR,
11608 "%s: IE length is wrong %d", __func__, eLen);
11609 return FALSE;
11610 }
11611 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
11612 {
11613 /* OUI - 0x00 0X50 0XF2
11614 WPA Information Element - 0x01
11615 WPA version - 0x01*/
11616 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
11617 return TRUE;
11618 }
11619 ie += eLen;
11620 remLen -= eLen;
11621 }
11622 return FALSE;
11623}
11624
11625/*
Jeff Johnson295189b2012-06-20 16:38:30 -070011626 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011627 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011628 * parameters during connect operation.
11629 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011630int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011631 struct cfg80211_connect_params *req
11632 )
11633{
11634 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011635 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011636 ENTER();
11637
11638 /*set wpa version*/
11639 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
11640
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011641 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011642 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053011643 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011644 {
11645 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11646 }
11647 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
11648 {
11649 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11650 }
11651 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011652
11653 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011654 pWextState->wpaVersion);
11655
11656 /*set authentication type*/
11657 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
11658
11659 if (0 > status)
11660 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011661 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011662 "%s: failed to set authentication type ", __func__);
11663 return status;
11664 }
11665
11666 /*set key mgmt type*/
11667 if (req->crypto.n_akm_suites)
11668 {
11669 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
11670 if (0 > status)
11671 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011672 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070011673 __func__);
11674 return status;
11675 }
11676 }
11677
11678 /*set pairwise cipher type*/
11679 if (req->crypto.n_ciphers_pairwise)
11680 {
11681 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
11682 req->crypto.ciphers_pairwise[0], true);
11683 if (0 > status)
11684 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011685 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011686 "%s: failed to set unicast cipher type", __func__);
11687 return status;
11688 }
11689 }
11690 else
11691 {
11692 /*Reset previous cipher suite to none*/
11693 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
11694 if (0 > status)
11695 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011696 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011697 "%s: failed to set unicast cipher type", __func__);
11698 return status;
11699 }
11700 }
11701
11702 /*set group cipher type*/
11703 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
11704 false);
11705
11706 if (0 > status)
11707 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011708 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070011709 __func__);
11710 return status;
11711 }
11712
Chet Lanctot186b5732013-03-18 10:26:30 -070011713#ifdef WLAN_FEATURE_11W
11714 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
11715#endif
11716
Jeff Johnson295189b2012-06-20 16:38:30 -070011717 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
11718 if (req->ie_len)
11719 {
11720 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
11721 if ( 0 > status)
11722 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011723 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011724 __func__);
11725 return status;
11726 }
11727 }
11728
11729 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011730 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011731 {
11732 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
11733 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
11734 )
11735 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011736 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070011737 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
11738 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011739 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011740 __func__);
11741 return -EOPNOTSUPP;
11742 }
11743 else
11744 {
11745 u8 key_len = req->key_len;
11746 u8 key_idx = req->key_idx;
11747
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011748 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011749 && (CSR_MAX_NUM_KEY > key_idx)
11750 )
11751 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011752 hddLog(VOS_TRACE_LEVEL_INFO,
11753 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011754 __func__, key_idx, key_len);
11755 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011756 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011757 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011758 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011759 (u8)key_len;
11760 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
11761 }
11762 }
11763 }
11764 }
11765
11766 return status;
11767}
11768
11769/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011770 * FUNCTION: wlan_hdd_try_disconnect
11771 * This function is used to disconnect from previous
11772 * connection
11773 */
11774static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
11775{
11776 long ret = 0;
11777 hdd_station_ctx_t *pHddStaCtx;
11778 eMib_dot11DesiredBssType connectedBssType;
11779
11780 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11781
11782 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
11783
11784 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
11785 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
11786 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
11787 {
11788 /* Issue disconnect to CSR */
11789 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11790 if( eHAL_STATUS_SUCCESS ==
11791 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11792 pAdapter->sessionId,
11793 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11794 {
11795 ret = wait_for_completion_interruptible_timeout(
11796 &pAdapter->disconnect_comp_var,
11797 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11798 if (0 >= ret)
11799 {
11800 hddLog(LOGE, FL("Failed to receive disconnect event"));
11801 return -EALREADY;
11802 }
11803 }
11804 }
11805 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
11806 {
11807 ret = wait_for_completion_interruptible_timeout(
11808 &pAdapter->disconnect_comp_var,
11809 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11810 if (0 >= ret)
11811 {
11812 hddLog(LOGE, FL("Failed to receive disconnect event"));
11813 return -EALREADY;
11814 }
11815 }
11816
11817 return 0;
11818}
11819
11820/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053011821 * FUNCTION: __wlan_hdd_cfg80211_connect
11822 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011823 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011824static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011825 struct net_device *ndev,
11826 struct cfg80211_connect_params *req
11827 )
11828{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011829 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011830 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011831 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053011832 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011833
11834 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011835
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011836 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11837 TRACE_CODE_HDD_CFG80211_CONNECT,
11838 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011839 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011840 "%s: device_mode = %s (%d)", __func__,
11841 hdd_device_modetoString(pAdapter->device_mode),
11842 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011843
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011844 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011845 if (!pHddCtx)
11846 {
11847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11848 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011849 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011850 }
11851
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011852 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011853 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011854 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011855 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011856 }
11857
Agarwal Ashish51325b52014-06-16 16:50:49 +053011858 if (vos_max_concurrent_connections_reached()) {
11859 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11860 return -ECONNREFUSED;
11861 }
11862
Jeff Johnson295189b2012-06-20 16:38:30 -070011863#ifdef WLAN_BTAMP_FEATURE
11864 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011865 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070011866 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011867 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011868 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011869 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070011870 }
11871#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011872
11873 //If Device Mode is Station Concurrent Sessions Exit BMps
11874 //P2P Mode will be taken care in Open/close adapter
11875 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011876 (vos_concurrent_open_sessions_running())) {
11877 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
11878 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011879 }
11880
11881 /*Try disconnecting if already in connected state*/
11882 status = wlan_hdd_try_disconnect(pAdapter);
11883 if ( 0 > status)
11884 {
11885 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11886 " connection"));
11887 return -EALREADY;
11888 }
11889
Jeff Johnson295189b2012-06-20 16:38:30 -070011890 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011891 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070011892
11893 if ( 0 > status)
11894 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011895 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070011896 __func__);
11897 return status;
11898 }
Mohit Khanna765234a2012-09-11 15:08:35 -070011899 if ( req->channel )
11900 {
11901 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
11902 req->ssid_len, req->bssid,
11903 req->channel->hw_value);
11904 }
11905 else
11906 {
11907 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011908 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070011909 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011910
11911 if (0 > status)
11912 {
11913 //ReEnable BMPS if disabled
11914 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
11915 (NULL != pHddCtx))
11916 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011917 if (pHddCtx->hdd_wlan_suspended)
11918 {
11919 hdd_set_pwrparams(pHddCtx);
11920 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011921 //ReEnable Bmps and Imps back
11922 hdd_enable_bmps_imps(pHddCtx);
11923 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011924 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011925 return status;
11926 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011927 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011928 EXIT();
11929 return status;
11930}
11931
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011932static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
11933 struct net_device *ndev,
11934 struct cfg80211_connect_params *req)
11935{
11936 int ret;
11937 vos_ssr_protect(__func__);
11938 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
11939 vos_ssr_unprotect(__func__);
11940
11941 return ret;
11942}
Jeff Johnson295189b2012-06-20 16:38:30 -070011943
11944/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011945 * FUNCTION: wlan_hdd_disconnect
11946 * This function is used to issue a disconnect request to SME
11947 */
11948int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
11949{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011950 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011951 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011952 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011953 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011954
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011955 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011956
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011957 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011958 if (0 != status)
11959 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011960 return status;
11961 }
11962
11963 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011964
Agarwal Ashish47d18112014-08-04 19:55:07 +053011965 /* Need to apply spin lock before decreasing active sessions
11966 * as there can be chance for double decrement if context switch
11967 * Calls hdd_DisConnectHandler.
11968 */
11969
11970 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011971 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11972 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011973 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11974 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053011975 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
11976 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011977
Abhishek Singhf4669da2014-05-26 15:07:49 +053011978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053011979 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
11980
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011981 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011982
Mihir Shete182a0b22014-08-18 16:08:48 +053011983 /*
11984 * stop tx queues before deleting STA/BSS context from the firmware.
11985 * tx has to be disabled because the firmware can get busy dropping
11986 * the tx frames after BSS/STA has been deleted and will not send
11987 * back a response resulting in WDI timeout
11988 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053011989 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053011990 netif_tx_disable(pAdapter->dev);
11991 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011992
Mihir Shete182a0b22014-08-18 16:08:48 +053011993 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011994 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11995 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011996 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
11997 {
11998 hddLog(VOS_TRACE_LEVEL_INFO,
11999 FL("status = %d, already disconnected"),
12000 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012001
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012002 }
12003 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012004 {
12005 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012006 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012007 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012008 result = -EINVAL;
12009 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012010 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012011 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012012 &pAdapter->disconnect_comp_var,
12013 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012014 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012015 {
12016 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012017 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012018 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012019 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012020 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012021 {
12022 hddLog(VOS_TRACE_LEVEL_ERROR,
12023 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012024 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012025 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012026disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012027 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12028 FL("Set HDD connState to eConnectionState_NotConnected"));
12029 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
12030
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012031 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012032 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012033}
12034
12035
12036/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012037 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070012038 * This function is used to issue a disconnect request to SME
12039 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012040static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012041 struct net_device *dev,
12042 u16 reason
12043 )
12044{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012045 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012046 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012047 tCsrRoamProfile *pRoamProfile;
12048 hdd_station_ctx_t *pHddStaCtx;
12049 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012050#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012051 tANI_U8 staIdx;
12052#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012053
Jeff Johnson295189b2012-06-20 16:38:30 -070012054 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012055
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012056 if (!pAdapter) {
12057 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
12058 return -EINVAL;
12059 }
12060
12061 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12062 if (!pHddStaCtx) {
12063 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
12064 return -EINVAL;
12065 }
12066
12067 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12068 status = wlan_hdd_validate_context(pHddCtx);
12069 if (0 != status)
12070 {
12071 return status;
12072 }
12073
12074 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
12075
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012076 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12077 TRACE_CODE_HDD_CFG80211_DISCONNECT,
12078 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012079 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
12080 __func__, hdd_device_modetoString(pAdapter->device_mode),
12081 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012082
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012083 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
12084 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070012085
Jeff Johnson295189b2012-06-20 16:38:30 -070012086 if (NULL != pRoamProfile)
12087 {
12088 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012089 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
12090 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070012091 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012092 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070012093 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012094 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012095 switch(reason)
12096 {
12097 case WLAN_REASON_MIC_FAILURE:
12098 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
12099 break;
12100
12101 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
12102 case WLAN_REASON_DISASSOC_AP_BUSY:
12103 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
12104 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
12105 break;
12106
12107 case WLAN_REASON_PREV_AUTH_NOT_VALID:
12108 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053012109 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070012110 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
12111 break;
12112
Jeff Johnson295189b2012-06-20 16:38:30 -070012113 default:
12114 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
12115 break;
12116 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012117 pScanInfo = &pHddCtx->scan_info;
12118 if (pScanInfo->mScanPending)
12119 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012120 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012121 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012122 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012123 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012124 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012125
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012126#ifdef FEATURE_WLAN_TDLS
12127 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012128 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012129 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012130 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
12131 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012132 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012133 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012134 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012135 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012136 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012137 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012138 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012139 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012140 pAdapter->sessionId,
12141 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012142 }
12143 }
12144#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012145 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012146 status = wlan_hdd_disconnect(pAdapter, reasonCode);
12147 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070012148 {
12149 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012150 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012151 __func__, (int)status );
12152 return -EINVAL;
12153 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012154 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012155 else
12156 {
12157 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
12158 "called while in %d state", __func__,
12159 pHddStaCtx->conn_info.connState);
12160 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012161 }
12162 else
12163 {
12164 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
12165 }
12166
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012167 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012168 return status;
12169}
12170
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012171static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
12172 struct net_device *dev,
12173 u16 reason
12174 )
12175{
12176 int ret;
12177 vos_ssr_protect(__func__);
12178 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
12179 vos_ssr_unprotect(__func__);
12180
12181 return ret;
12182}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012183
Jeff Johnson295189b2012-06-20 16:38:30 -070012184/*
12185 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012186 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012187 * settings in IBSS mode.
12188 */
12189static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012190 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012191 struct cfg80211_ibss_params *params
12192 )
12193{
12194 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012195 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012196 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12197 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012198
Jeff Johnson295189b2012-06-20 16:38:30 -070012199 ENTER();
12200
12201 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070012202 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070012203
12204 if (params->ie_len && ( NULL != params->ie) )
12205 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012206 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12207 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012208 {
12209 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12210 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12211 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012212 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012213 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012214 tDot11fIEWPA dot11WPAIE;
12215 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012216 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012217
Wilson Yang00256342013-10-10 23:13:38 -070012218 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012219 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12220 params->ie_len, DOT11F_EID_WPA);
12221 if ( NULL != ie )
12222 {
12223 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12224 // Unpack the WPA IE
12225 //Skip past the EID byte and length byte - and four byte WiFi OUI
12226 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
12227 &ie[2+4],
12228 ie[1] - 4,
12229 &dot11WPAIE);
12230 /*Extract the multicast cipher, the encType for unicast
12231 cipher for wpa-none is none*/
12232 encryptionType =
12233 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
12234 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012235 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012236
Jeff Johnson295189b2012-06-20 16:38:30 -070012237 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
12238
12239 if (0 > status)
12240 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012241 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012242 __func__);
12243 return status;
12244 }
12245 }
12246
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012247 pWextState->roamProfile.AuthType.authType[0] =
12248 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012249 eCSR_AUTH_TYPE_OPEN_SYSTEM;
12250
12251 if (params->privacy)
12252 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012253 /* Security enabled IBSS, At this time there is no information available
12254 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070012255 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012256 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070012257 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012258 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070012259 *enable privacy bit in beacons */
12260
12261 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12262 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012263 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
12264 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070012265 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12266 pWextState->roamProfile.EncryptionType.numEntries = 1;
12267 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070012268 return status;
12269}
12270
12271/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012272 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012273 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012274 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012275static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012276 struct net_device *dev,
12277 struct cfg80211_ibss_params *params
12278 )
12279{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012280 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012281 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12282 tCsrRoamProfile *pRoamProfile;
12283 int status;
krunal sonie9002db2013-11-25 14:24:17 -080012284 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012285 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12286 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012287
12288 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012289
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012290 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12291 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
12292 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012293 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012294 "%s: device_mode = %s (%d)", __func__,
12295 hdd_device_modetoString(pAdapter->device_mode),
12296 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012297
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012298 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012299 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012300 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012301 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012302 }
12303
12304 if (NULL == pWextState)
12305 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012306 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012307 __func__);
12308 return -EIO;
12309 }
12310
Agarwal Ashish51325b52014-06-16 16:50:49 +053012311 if (vos_max_concurrent_connections_reached()) {
12312 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12313 return -ECONNREFUSED;
12314 }
12315
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012316 /*Try disconnecting if already in connected state*/
12317 status = wlan_hdd_try_disconnect(pAdapter);
12318 if ( 0 > status)
12319 {
12320 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12321 " IBSS connection"));
12322 return -EALREADY;
12323 }
12324
Jeff Johnson295189b2012-06-20 16:38:30 -070012325 pRoamProfile = &pWextState->roamProfile;
12326
12327 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
12328 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012329 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012330 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012331 return -EINVAL;
12332 }
12333
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012334 /* BSSID is provided by upper layers hence no need to AUTO generate */
12335 if (NULL != params->bssid) {
12336 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12337 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
12338 hddLog (VOS_TRACE_LEVEL_ERROR,
12339 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12340 return -EIO;
12341 }
12342 }
krunal sonie9002db2013-11-25 14:24:17 -080012343 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
12344 {
12345 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12346 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
12347 {
12348 hddLog (VOS_TRACE_LEVEL_ERROR,
12349 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12350 return -EIO;
12351 }
12352 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
12353 if (!params->bssid)
12354 {
12355 hddLog (VOS_TRACE_LEVEL_ERROR,
12356 "%s:Failed memory allocation", __func__);
12357 return -EIO;
12358 }
12359 vos_mem_copy((v_U8_t *)params->bssid,
12360 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
12361 VOS_MAC_ADDR_SIZE);
12362 alloc_bssid = VOS_TRUE;
12363 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012364
Jeff Johnson295189b2012-06-20 16:38:30 -070012365 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070012366 if (NULL !=
12367#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12368 params->chandef.chan)
12369#else
12370 params->channel)
12371#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012372 {
12373 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012374 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12375 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
12376 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12377 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012378
12379 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012380 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070012381 ieee80211_frequency_to_channel(
12382#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12383 params->chandef.chan->center_freq);
12384#else
12385 params->channel->center_freq);
12386#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012387
12388 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12389 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070012390 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012391 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
12392 __func__);
12393 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012394 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012395
12396 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012397 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012398 if (channelNum == validChan[indx])
12399 {
12400 break;
12401 }
12402 }
12403 if (indx >= numChans)
12404 {
12405 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012406 __func__, channelNum);
12407 return -EINVAL;
12408 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012409 /* Set the Operational Channel */
12410 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
12411 channelNum);
12412 pRoamProfile->ChannelInfo.numOfChannels = 1;
12413 pHddStaCtx->conn_info.operationChannel = channelNum;
12414 pRoamProfile->ChannelInfo.ChannelList =
12415 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070012416 }
12417
12418 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012419 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070012420 if (status < 0)
12421 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012422 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070012423 __func__);
12424 return status;
12425 }
12426
12427 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012428 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012429 params->ssid_len, params->bssid,
12430 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012431
12432 if (0 > status)
12433 {
12434 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
12435 return status;
12436 }
12437
krunal sonie9002db2013-11-25 14:24:17 -080012438 if (NULL != params->bssid &&
12439 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
12440 alloc_bssid == VOS_TRUE)
12441 {
12442 vos_mem_free(params->bssid);
12443 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012444 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012445 return 0;
12446}
12447
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012448static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
12449 struct net_device *dev,
12450 struct cfg80211_ibss_params *params
12451 )
12452{
12453 int ret = 0;
12454
12455 vos_ssr_protect(__func__);
12456 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
12457 vos_ssr_unprotect(__func__);
12458
12459 return ret;
12460}
12461
Jeff Johnson295189b2012-06-20 16:38:30 -070012462/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012463 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012464 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012465 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012466static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012467 struct net_device *dev
12468 )
12469{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012470 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012471 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12472 tCsrRoamProfile *pRoamProfile;
12473 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012474 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012475
12476 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012477
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012478 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12479 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
12480 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012481 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012482 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012483 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012484 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012485 }
12486
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012487 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
12488 hdd_device_modetoString(pAdapter->device_mode),
12489 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012490 if (NULL == pWextState)
12491 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012492 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012493 __func__);
12494 return -EIO;
12495 }
12496
12497 pRoamProfile = &pWextState->roamProfile;
12498
12499 /* Issue disconnect only if interface type is set to IBSS */
12500 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
12501 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012502 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012503 __func__);
12504 return -EINVAL;
12505 }
12506
12507 /* Issue Disconnect request */
12508 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12509 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12510 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12511
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012512 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012513 return 0;
12514}
12515
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012516static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12517 struct net_device *dev
12518 )
12519{
12520 int ret = 0;
12521
12522 vos_ssr_protect(__func__);
12523 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12524 vos_ssr_unprotect(__func__);
12525
12526 return ret;
12527}
12528
Jeff Johnson295189b2012-06-20 16:38:30 -070012529/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012530 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012531 * This function is used to set the phy parameters
12532 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12533 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012534static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012535 u32 changed)
12536{
12537 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12538 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012539 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012540
12541 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012542
12543 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012544 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
12545 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012546
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012547 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012548 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012549 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012550 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012551 }
12552
Jeff Johnson295189b2012-06-20 16:38:30 -070012553 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
12554 {
12555 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
12556 WNI_CFG_RTS_THRESHOLD_STAMAX :
12557 wiphy->rts_threshold;
12558
12559 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012560 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070012561 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012562 hddLog(VOS_TRACE_LEVEL_ERROR,
12563 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012564 __func__, rts_threshold);
12565 return -EINVAL;
12566 }
12567
12568 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
12569 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012570 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012571 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012572 hddLog(VOS_TRACE_LEVEL_ERROR,
12573 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012574 __func__, rts_threshold);
12575 return -EIO;
12576 }
12577
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012578 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012579 rts_threshold);
12580 }
12581
12582 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
12583 {
12584 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
12585 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
12586 wiphy->frag_threshold;
12587
12588 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012589 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012590 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012591 hddLog(VOS_TRACE_LEVEL_ERROR,
12592 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012593 frag_threshold);
12594 return -EINVAL;
12595 }
12596
12597 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
12598 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012599 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012600 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012601 hddLog(VOS_TRACE_LEVEL_ERROR,
12602 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012603 __func__, frag_threshold);
12604 return -EIO;
12605 }
12606
12607 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
12608 frag_threshold);
12609 }
12610
12611 if ((changed & WIPHY_PARAM_RETRY_SHORT)
12612 || (changed & WIPHY_PARAM_RETRY_LONG))
12613 {
12614 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
12615 wiphy->retry_short :
12616 wiphy->retry_long;
12617
12618 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
12619 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
12620 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012621 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012622 __func__, retry_value);
12623 return -EINVAL;
12624 }
12625
12626 if (changed & WIPHY_PARAM_RETRY_SHORT)
12627 {
12628 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
12629 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012630 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012631 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012632 hddLog(VOS_TRACE_LEVEL_ERROR,
12633 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012634 __func__, retry_value);
12635 return -EIO;
12636 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012637 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012638 __func__, retry_value);
12639 }
12640 else if (changed & WIPHY_PARAM_RETRY_SHORT)
12641 {
12642 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
12643 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012644 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012645 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012646 hddLog(VOS_TRACE_LEVEL_ERROR,
12647 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012648 __func__, retry_value);
12649 return -EIO;
12650 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012651 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012652 __func__, retry_value);
12653 }
12654 }
12655
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012656 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012657 return 0;
12658}
12659
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012660static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
12661 u32 changed)
12662{
12663 int ret;
12664
12665 vos_ssr_protect(__func__);
12666 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
12667 vos_ssr_unprotect(__func__);
12668
12669 return ret;
12670}
12671
Jeff Johnson295189b2012-06-20 16:38:30 -070012672/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012673 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012674 * This function is used to set the txpower
12675 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012676static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012677#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12678 struct wireless_dev *wdev,
12679#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012680#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012681 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012682#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012683 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012684#endif
12685 int dbm)
12686{
12687 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012688 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012689 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12690 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012691 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012692
12693 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012694
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012695 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12696 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
12697 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012698 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012699 if (0 != status)
12700 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012701 return status;
12702 }
12703
12704 hHal = pHddCtx->hHal;
12705
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012706 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
12707 dbm, ccmCfgSetCallback,
12708 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012709 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012710 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012711 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
12712 return -EIO;
12713 }
12714
12715 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
12716 dbm);
12717
12718 switch(type)
12719 {
12720 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
12721 /* Fall through */
12722 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
12723 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
12724 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012725 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
12726 __func__);
12727 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012728 }
12729 break;
12730 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012731 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012732 __func__);
12733 return -EOPNOTSUPP;
12734 break;
12735 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012736 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
12737 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070012738 return -EIO;
12739 }
12740
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012741 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012742 return 0;
12743}
12744
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012745static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
12746#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12747 struct wireless_dev *wdev,
12748#endif
12749#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12750 enum tx_power_setting type,
12751#else
12752 enum nl80211_tx_power_setting type,
12753#endif
12754 int dbm)
12755{
12756 int ret;
12757 vos_ssr_protect(__func__);
12758 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
12759#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12760 wdev,
12761#endif
12762#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12763 type,
12764#else
12765 type,
12766#endif
12767 dbm);
12768 vos_ssr_unprotect(__func__);
12769
12770 return ret;
12771}
12772
Jeff Johnson295189b2012-06-20 16:38:30 -070012773/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012774 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012775 * This function is used to read the txpower
12776 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012777static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012778#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12779 struct wireless_dev *wdev,
12780#endif
12781 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070012782{
12783
12784 hdd_adapter_t *pAdapter;
12785 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012786 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012787
Jeff Johnsone7245742012-09-05 17:12:55 -070012788 ENTER();
12789
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012790 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012791 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012792 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012793 *dbm = 0;
12794 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012795 }
12796
Jeff Johnson295189b2012-06-20 16:38:30 -070012797 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
12798 if (NULL == pAdapter)
12799 {
12800 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
12801 return -ENOENT;
12802 }
12803
12804 wlan_hdd_get_classAstats(pAdapter);
12805 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
12806
Jeff Johnsone7245742012-09-05 17:12:55 -070012807 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012808 return 0;
12809}
12810
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012811static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
12812#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12813 struct wireless_dev *wdev,
12814#endif
12815 int *dbm)
12816{
12817 int ret;
12818
12819 vos_ssr_protect(__func__);
12820 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
12821#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12822 wdev,
12823#endif
12824 dbm);
12825 vos_ssr_unprotect(__func__);
12826
12827 return ret;
12828}
12829
12830
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012831static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070012832 u8* mac, struct station_info *sinfo)
12833{
12834 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12835 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12836 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053012837 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070012838
12839 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
12840 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012841
12842 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
12843 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
12844 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
12845 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
12846 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
12847 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
12848 tANI_U16 maxRate = 0;
12849 tANI_U16 myRate;
12850 tANI_U16 currentRate = 0;
12851 tANI_U8 maxSpeedMCS = 0;
12852 tANI_U8 maxMCSIdx = 0;
12853 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053012854 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012855 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012856 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012857
Leo Chang6f8870f2013-03-26 18:11:36 -070012858#ifdef WLAN_FEATURE_11AC
12859 tANI_U32 vht_mcs_map;
12860 eDataRate11ACMaxMcs vhtMaxMcs;
12861#endif /* WLAN_FEATURE_11AC */
12862
Jeff Johnsone7245742012-09-05 17:12:55 -070012863 ENTER();
12864
Jeff Johnson295189b2012-06-20 16:38:30 -070012865 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
12866 (0 == ssidlen))
12867 {
12868 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
12869 " Invalid ssidlen, %d", __func__, ssidlen);
12870 /*To keep GUI happy*/
12871 return 0;
12872 }
12873
Mukul Sharma811205f2014-07-09 21:07:30 +053012874 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
12875 {
12876 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12877 "%s: Roaming in progress, so unable to proceed this request", __func__);
12878 return 0;
12879 }
12880
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012881 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012882 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012883 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012884 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012885 }
12886
Jeff Johnson295189b2012-06-20 16:38:30 -070012887
Kiet Lam3b17fc82013-09-27 05:24:08 +053012888 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
12889 sinfo->filled |= STATION_INFO_SIGNAL;
12890
c_hpothu09f19542014-05-30 21:53:31 +053012891 wlan_hdd_get_station_stats(pAdapter);
12892 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
12893
12894 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053012895 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
12896 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053012897 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053012898 {
12899 rate_flags = pAdapter->maxRateFlags;
12900 }
c_hpothu44ff4e02014-05-08 00:13:57 +053012901
Jeff Johnson295189b2012-06-20 16:38:30 -070012902 //convert to the UI units of 100kbps
12903 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
12904
12905#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070012906 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 -070012907 sinfo->signal,
12908 pCfg->reportMaxLinkSpeed,
12909 myRate,
12910 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012911 (int) pCfg->linkSpeedRssiMid,
12912 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070012913 (int) rate_flags,
12914 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012915#endif //LINKSPEED_DEBUG_ENABLED
12916
12917 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
12918 {
12919 // we do not want to necessarily report the current speed
12920 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
12921 {
12922 // report the max possible speed
12923 rssidx = 0;
12924 }
12925 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
12926 {
12927 // report the max possible speed with RSSI scaling
12928 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
12929 {
12930 // report the max possible speed
12931 rssidx = 0;
12932 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012933 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070012934 {
12935 // report middle speed
12936 rssidx = 1;
12937 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012938 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
12939 {
12940 // report middle speed
12941 rssidx = 2;
12942 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012943 else
12944 {
12945 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012946 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070012947 }
12948 }
12949 else
12950 {
12951 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
12952 hddLog(VOS_TRACE_LEVEL_ERROR,
12953 "%s: Invalid value for reportMaxLinkSpeed: %u",
12954 __func__, pCfg->reportMaxLinkSpeed);
12955 rssidx = 0;
12956 }
12957
12958 maxRate = 0;
12959
12960 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012961 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
12962 OperationalRates, &ORLeng))
12963 {
12964 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12965 /*To keep GUI happy*/
12966 return 0;
12967 }
12968
Jeff Johnson295189b2012-06-20 16:38:30 -070012969 for (i = 0; i < ORLeng; i++)
12970 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012971 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012972 {
12973 /* Validate Rate Set */
12974 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
12975 {
12976 currentRate = supported_data_rate[j].supported_rate[rssidx];
12977 break;
12978 }
12979 }
12980 /* Update MAX rate */
12981 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12982 }
12983
12984 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012985 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
12986 ExtendedRates, &ERLeng))
12987 {
12988 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12989 /*To keep GUI happy*/
12990 return 0;
12991 }
12992
Jeff Johnson295189b2012-06-20 16:38:30 -070012993 for (i = 0; i < ERLeng; i++)
12994 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012995 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012996 {
12997 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
12998 {
12999 currentRate = supported_data_rate[j].supported_rate[rssidx];
13000 break;
13001 }
13002 }
13003 /* Update MAX rate */
13004 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13005 }
c_hpothu79aab322014-07-14 21:11:01 +053013006
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013007 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053013008 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013009 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053013010 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070013011 {
c_hpothu79aab322014-07-14 21:11:01 +053013012 if (rate_flags & eHAL_TX_RATE_VHT80)
13013 mode = 2;
13014 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
13015 mode = 1;
13016 else
13017 mode = 0;
13018
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013019 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
13020 MCSRates, &MCSLeng))
13021 {
13022 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13023 /*To keep GUI happy*/
13024 return 0;
13025 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013026 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070013027#ifdef WLAN_FEATURE_11AC
13028 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013029 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070013030 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013031 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013032 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070013033 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070013034 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013035 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013036 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013037 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070013038 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013039 maxMCSIdx = 7;
13040 }
13041 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
13042 {
13043 maxMCSIdx = 8;
13044 }
13045 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
13046 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013047 //VHT20 is supporting 0~8
13048 if (rate_flags & eHAL_TX_RATE_VHT20)
13049 maxMCSIdx = 8;
13050 else
13051 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070013052 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013053
c_hpothu79aab322014-07-14 21:11:01 +053013054 if (0 != rssidx)/*check for scaled */
13055 {
13056 //get middle rate MCS index if rssi=1/2
13057 for (i=0; i <= maxMCSIdx; i++)
13058 {
13059 if (sinfo->signal <= rssiMcsTbl[mode][i])
13060 {
13061 maxMCSIdx = i;
13062 break;
13063 }
13064 }
13065 }
13066
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013067 if (rate_flags & eHAL_TX_RATE_VHT80)
13068 {
13069 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
13070 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
13071 }
13072 else if (rate_flags & eHAL_TX_RATE_VHT40)
13073 {
13074 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
13075 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
13076 }
13077 else if (rate_flags & eHAL_TX_RATE_VHT20)
13078 {
13079 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
13080 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
13081 }
13082
Leo Chang6f8870f2013-03-26 18:11:36 -070013083 maxSpeedMCS = 1;
13084 if (currentRate > maxRate)
13085 {
13086 maxRate = currentRate;
13087 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013088
Leo Chang6f8870f2013-03-26 18:11:36 -070013089 }
13090 else
13091#endif /* WLAN_FEATURE_11AC */
13092 {
13093 if (rate_flags & eHAL_TX_RATE_HT40)
13094 {
13095 rateFlag |= 1;
13096 }
13097 if (rate_flags & eHAL_TX_RATE_SGI)
13098 {
13099 rateFlag |= 2;
13100 }
13101
Girish Gowli01abcee2014-07-31 20:18:55 +053013102 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053013103 if (rssidx == 1 || rssidx == 2)
13104 {
13105 //get middle rate MCS index if rssi=1/2
13106 for (i=0; i <= 7; i++)
13107 {
13108 if (sinfo->signal <= rssiMcsTbl[mode][i])
13109 {
13110 temp = i+1;
13111 break;
13112 }
13113 }
13114 }
c_hpothu79aab322014-07-14 21:11:01 +053013115
13116 for (i = 0; i < MCSLeng; i++)
13117 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013118 for (j = 0; j < temp; j++)
13119 {
13120 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
13121 {
13122 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
13123 break;
13124 }
13125 }
13126 if ((j < temp) && (currentRate > maxRate))
13127 {
13128 maxRate = currentRate;
13129 maxSpeedMCS = 1;
13130 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
13131 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013132 }
13133 }
13134 }
13135
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013136 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
13137 {
13138 maxRate = myRate;
13139 maxSpeedMCS = 1;
13140 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13141 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013142 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053013143 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070013144 {
13145 maxRate = myRate;
13146 if (rate_flags & eHAL_TX_RATE_LEGACY)
13147 {
13148 maxSpeedMCS = 0;
13149 }
13150 else
13151 {
13152 maxSpeedMCS = 1;
13153 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13154 }
13155 }
13156
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013157 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070013158 {
13159 sinfo->txrate.legacy = maxRate;
13160#ifdef LINKSPEED_DEBUG_ENABLED
13161 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
13162#endif //LINKSPEED_DEBUG_ENABLED
13163 }
13164 else
13165 {
13166 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070013167#ifdef WLAN_FEATURE_11AC
13168 sinfo->txrate.nss = 1;
13169 if (rate_flags & eHAL_TX_RATE_VHT80)
13170 {
13171 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013172 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070013173 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013174 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070013175 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013176 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13177 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13178 }
13179 else if (rate_flags & eHAL_TX_RATE_VHT20)
13180 {
13181 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13182 }
13183#endif /* WLAN_FEATURE_11AC */
13184 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
13185 {
13186 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13187 if (rate_flags & eHAL_TX_RATE_HT40)
13188 {
13189 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13190 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013191 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013192 if (rate_flags & eHAL_TX_RATE_SGI)
13193 {
13194 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13195 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013196
Jeff Johnson295189b2012-06-20 16:38:30 -070013197#ifdef LINKSPEED_DEBUG_ENABLED
13198 pr_info("Reporting MCS rate %d flags %x\n",
13199 sinfo->txrate.mcs,
13200 sinfo->txrate.flags );
13201#endif //LINKSPEED_DEBUG_ENABLED
13202 }
13203 }
13204 else
13205 {
13206 // report current rate instead of max rate
13207
13208 if (rate_flags & eHAL_TX_RATE_LEGACY)
13209 {
13210 //provide to the UI in units of 100kbps
13211 sinfo->txrate.legacy = myRate;
13212#ifdef LINKSPEED_DEBUG_ENABLED
13213 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
13214#endif //LINKSPEED_DEBUG_ENABLED
13215 }
13216 else
13217 {
13218 //must be MCS
13219 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013220#ifdef WLAN_FEATURE_11AC
13221 sinfo->txrate.nss = 1;
13222 if (rate_flags & eHAL_TX_RATE_VHT80)
13223 {
13224 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13225 }
13226 else
13227#endif /* WLAN_FEATURE_11AC */
13228 {
13229 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13230 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013231 if (rate_flags & eHAL_TX_RATE_SGI)
13232 {
13233 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13234 }
13235 if (rate_flags & eHAL_TX_RATE_HT40)
13236 {
13237 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13238 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013239#ifdef WLAN_FEATURE_11AC
13240 else if (rate_flags & eHAL_TX_RATE_VHT80)
13241 {
13242 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
13243 }
13244#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070013245#ifdef LINKSPEED_DEBUG_ENABLED
13246 pr_info("Reporting actual MCS rate %d flags %x\n",
13247 sinfo->txrate.mcs,
13248 sinfo->txrate.flags );
13249#endif //LINKSPEED_DEBUG_ENABLED
13250 }
13251 }
13252 sinfo->filled |= STATION_INFO_TX_BITRATE;
13253
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013254 sinfo->tx_packets =
13255 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
13256 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
13257 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
13258 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
13259
13260 sinfo->tx_retries =
13261 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
13262 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
13263 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
13264 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
13265
13266 sinfo->tx_failed =
13267 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
13268 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
13269 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
13270 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
13271
13272 sinfo->filled |=
13273 STATION_INFO_TX_PACKETS |
13274 STATION_INFO_TX_RETRIES |
13275 STATION_INFO_TX_FAILED;
13276
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013277 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13278 TRACE_CODE_HDD_CFG80211_GET_STA,
13279 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013280 EXIT();
13281 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013282}
13283
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013284static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13285 u8* mac, struct station_info *sinfo)
13286{
13287 int ret;
13288
13289 vos_ssr_protect(__func__);
13290 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
13291 vos_ssr_unprotect(__func__);
13292
13293 return ret;
13294}
13295
13296static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070013297 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070013298{
13299 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013300 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013301 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013302 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013303
Jeff Johnsone7245742012-09-05 17:12:55 -070013304 ENTER();
13305
Jeff Johnson295189b2012-06-20 16:38:30 -070013306 if (NULL == pAdapter)
13307 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013308 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013309 return -ENODEV;
13310 }
13311
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013312 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13313 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
13314 pAdapter->sessionId, timeout));
13315
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013316 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013317 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013318 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013319 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013320 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013321 }
13322
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013323 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
13324 (TRUE == pHddCtx->hdd_wlan_suspended) &&
13325 (pHddCtx->cfg_ini->fhostArpOffload) &&
13326 (eConnectionState_Associated ==
13327 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13328 {
Amar Singhald53568e2013-09-26 11:03:45 -070013329
13330 hddLog(VOS_TRACE_LEVEL_INFO,
13331 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053013332 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013333 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13334 {
13335 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013336 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013337 __func__, vos_status);
13338 }
13339 }
13340
Jeff Johnson295189b2012-06-20 16:38:30 -070013341 /**The get power cmd from the supplicant gets updated by the nl only
13342 *on successful execution of the function call
13343 *we are oppositely mapped w.r.t mode in the driver
13344 **/
13345 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
13346
13347 if (VOS_STATUS_E_FAILURE == vos_status)
13348 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013349 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13350 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013351 return -EINVAL;
13352 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013353 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013354 return 0;
13355}
13356
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013357static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
13358 struct net_device *dev, bool mode, int timeout)
13359{
13360 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013361
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013362 vos_ssr_protect(__func__);
13363 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
13364 vos_ssr_unprotect(__func__);
13365
13366 return ret;
13367}
Jeff Johnson295189b2012-06-20 16:38:30 -070013368#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013369static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
13370 struct net_device *netdev,
13371 u8 key_index)
13372{
13373 ENTER();
13374 return 0;
13375}
13376
Jeff Johnson295189b2012-06-20 16:38:30 -070013377static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013378 struct net_device *netdev,
13379 u8 key_index)
13380{
13381 int ret;
13382 vos_ssr_protect(__func__);
13383 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
13384 vos_ssr_unprotect(__func__);
13385 return ret;
13386}
13387#endif //LINUX_VERSION_CODE
13388
13389#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13390static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13391 struct net_device *dev,
13392 struct ieee80211_txq_params *params)
13393{
13394 ENTER();
13395 return 0;
13396}
13397#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13398static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13399 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013400{
Jeff Johnsone7245742012-09-05 17:12:55 -070013401 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013402 return 0;
13403}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013404#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070013405
13406#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13407static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013408 struct net_device *dev,
13409 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013410{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013411 int ret;
13412
13413 vos_ssr_protect(__func__);
13414 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
13415 vos_ssr_unprotect(__func__);
13416 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013417}
13418#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13419static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
13420 struct ieee80211_txq_params *params)
13421{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013422 int ret;
13423
13424 vos_ssr_protect(__func__);
13425 ret = __wlan_hdd_set_txq_params(wiphy, params);
13426 vos_ssr_unprotect(__func__);
13427 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013428}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013429#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013430
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013431static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013432 struct net_device *dev,
13433 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070013434{
13435 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013436 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013437 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013438 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013439 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013440 v_CONTEXT_t pVosContext = NULL;
13441 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013442
Jeff Johnsone7245742012-09-05 17:12:55 -070013443 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013444
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013445 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070013446 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013447 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013448 return -EINVAL;
13449 }
13450
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013451 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13452 TRACE_CODE_HDD_CFG80211_DEL_STA,
13453 pAdapter->sessionId, pAdapter->device_mode));
13454
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013455 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13456 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013457 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013458 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013459 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013460 }
13461
Jeff Johnson295189b2012-06-20 16:38:30 -070013462 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013463 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013464 )
13465 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013466 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13467 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13468 if(pSapCtx == NULL){
13469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13470 FL("psapCtx is NULL"));
13471 return -ENOENT;
13472 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013473 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013474 {
13475 v_U16_t i;
13476 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13477 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013478 if ((pSapCtx->aStaInfo[i].isUsed) &&
13479 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070013480 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013481 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013482 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013483 ETHER_ADDR_LEN);
13484
Jeff Johnson295189b2012-06-20 16:38:30 -070013485 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013486 "%s: Delete STA with MAC::"
13487 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013488 __func__,
13489 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
13490 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013491 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013492 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013493 }
13494 }
13495 }
13496 else
13497 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013498
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013499 vos_status = hdd_softap_GetStaId(pAdapter,
13500 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013501 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13502 {
13503 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013504 "%s: Skip this DEL STA as this is not used::"
13505 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013506 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013507 return -ENOENT;
13508 }
13509
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013510 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013511 {
13512 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013513 "%s: Skip this DEL STA as deauth is in progress::"
13514 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013515 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013516 return -ENOENT;
13517 }
13518
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013519 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013520
Jeff Johnson295189b2012-06-20 16:38:30 -070013521 hddLog(VOS_TRACE_LEVEL_INFO,
13522 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013523 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013524 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013525 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013526
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013527 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013528 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13529 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013530 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013531 hddLog(VOS_TRACE_LEVEL_INFO,
13532 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013533 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013534 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013535 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013536 return -ENOENT;
13537 }
13538
Jeff Johnson295189b2012-06-20 16:38:30 -070013539 }
13540 }
13541
13542 EXIT();
13543
13544 return 0;
13545}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013546
13547#ifdef CFG80211_DEL_STA_V2
13548static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13549 struct net_device *dev,
13550 struct station_del_parameters *param)
13551#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013552static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13553 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013554#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013555{
13556 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013557 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070013558
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013559 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013560
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013561#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013562 if (NULL == param) {
13563 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013564 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013565 return -EINVAL;
13566 }
13567
13568 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
13569 param->subtype, &delStaParams);
13570
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013571#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053013572 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013573 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013574#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013575 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
13576
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013577 vos_ssr_unprotect(__func__);
13578
13579 return ret;
13580}
13581
13582static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013583 struct net_device *dev, u8 *mac, struct station_parameters *params)
13584{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013585 hdd_adapter_t *pAdapter;
13586 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013587 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013588#ifdef FEATURE_WLAN_TDLS
13589 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013590
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013591 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013592
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013593 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13594 if (NULL == pAdapter)
13595 {
13596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13597 "%s: Adapter is NULL",__func__);
13598 return -EINVAL;
13599 }
13600 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13601 status = wlan_hdd_validate_context(pHddCtx);
13602 if (0 != status)
13603 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013604 return status;
13605 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013606
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013607 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13608 TRACE_CODE_HDD_CFG80211_ADD_STA,
13609 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013610 mask = params->sta_flags_mask;
13611
13612 set = params->sta_flags_set;
13613
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053013614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013615 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
13616 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013617
13618 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13619 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013620 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013621 }
13622 }
13623#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013624 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013625 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013626}
13627
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013628static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
13629 struct net_device *dev, u8 *mac, struct station_parameters *params)
13630{
13631 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013632
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013633 vos_ssr_protect(__func__);
13634 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
13635 vos_ssr_unprotect(__func__);
13636
13637 return ret;
13638}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013639#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070013640
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013641static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070013642 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013643{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013644 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13645 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013646 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013647 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013648 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013649 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070013650
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013651 ENTER();
13652
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013653 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013654 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013655 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013656 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013657 return -EINVAL;
13658 }
13659
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013660 if (!pmksa) {
13661 hddLog(LOGE, FL("pmksa is NULL"));
13662 return -EINVAL;
13663 }
13664
13665 if (!pmksa->bssid || !pmksa->pmkid) {
13666 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
13667 pmksa->bssid, pmksa->pmkid);
13668 return -EINVAL;
13669 }
13670
13671 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
13672 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13673
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013674 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13675 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013676 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013677 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013678 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013679 }
13680
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013681 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013682 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13683
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013684 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
13685 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013686
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013687 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013688 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013689 &pmk_id, 1, FALSE);
13690
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013691 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13692 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
13693 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013694
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013695 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013696 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013697}
13698
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013699static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
13700 struct cfg80211_pmksa *pmksa)
13701{
13702 int ret;
13703
13704 vos_ssr_protect(__func__);
13705 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
13706 vos_ssr_unprotect(__func__);
13707
13708 return ret;
13709}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013710
Wilson Yang6507c4e2013-10-01 20:11:19 -070013711
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013712static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070013713 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013714{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013715 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13716 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013717 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013718 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013719
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013720 ENTER();
13721
Wilson Yang6507c4e2013-10-01 20:11:19 -070013722 /* Validate pAdapter */
13723 if (NULL == pAdapter)
13724 {
13725 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
13726 return -EINVAL;
13727 }
13728
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013729 if (!pmksa) {
13730 hddLog(LOGE, FL("pmksa is NULL"));
13731 return -EINVAL;
13732 }
13733
13734 if (!pmksa->bssid) {
13735 hddLog(LOGE, FL("pmksa->bssid is NULL"));
13736 return -EINVAL;
13737 }
13738
Kiet Lam98c46a12014-10-31 15:34:57 -070013739 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
13740 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13741
Wilson Yang6507c4e2013-10-01 20:11:19 -070013742 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13743 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070013744 if (0 != status)
13745 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070013746 return status;
13747 }
13748
13749 /*Retrieve halHandle*/
13750 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13751
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013752 /* Delete the PMKID CSR cache */
13753 if (eHAL_STATUS_SUCCESS !=
13754 sme_RoamDelPMKIDfromCache(halHandle,
13755 pAdapter->sessionId, pmksa->bssid, FALSE)) {
13756 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
13757 MAC_ADDR_ARRAY(pmksa->bssid));
13758 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013759 }
13760
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013761 EXIT();
13762 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013763}
13764
Wilson Yang6507c4e2013-10-01 20:11:19 -070013765
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013766static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
13767 struct cfg80211_pmksa *pmksa)
13768{
13769 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013770
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013771 vos_ssr_protect(__func__);
13772 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
13773 vos_ssr_unprotect(__func__);
13774
13775 return ret;
13776
13777}
13778
13779static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013780{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013781 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13782 tHalHandle halHandle;
13783 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013784 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013785
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013786 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070013787
13788 /* Validate pAdapter */
13789 if (NULL == pAdapter)
13790 {
13791 hddLog(VOS_TRACE_LEVEL_ERROR,
13792 "%s: Invalid Adapter" ,__func__);
13793 return -EINVAL;
13794 }
13795
13796 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13797 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070013798 if (0 != status)
13799 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070013800 return status;
13801 }
13802
13803 /*Retrieve halHandle*/
13804 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13805
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013806 /* Flush the PMKID cache in CSR */
13807 if (eHAL_STATUS_SUCCESS !=
13808 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
13809 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
13810 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013811 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013812 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080013813 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013814}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013815
13816static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
13817{
13818 int ret;
13819
13820 vos_ssr_protect(__func__);
13821 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
13822 vos_ssr_unprotect(__func__);
13823
13824 return ret;
13825}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013826#endif
13827
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013828#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013829static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13830 struct net_device *dev,
13831 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013832{
13833 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13834 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013835 hdd_context_t *pHddCtx;
13836 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013837
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013838 ENTER();
13839
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013840 if (NULL == pAdapter)
13841 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013842 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013843 return -ENODEV;
13844 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013845 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13846 ret = wlan_hdd_validate_context(pHddCtx);
13847 if (0 != ret)
13848 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013849 return ret;
13850 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013851 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013852 if (NULL == pHddStaCtx)
13853 {
13854 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
13855 return -EINVAL;
13856 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013857
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013858 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13859 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
13860 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013861 // Added for debug on reception of Re-assoc Req.
13862 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
13863 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013864 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013865 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080013866 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013867 }
13868
13869#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080013870 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013871 ftie->ie_len);
13872#endif
13873
13874 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013875 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13876 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013877 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013878
13879 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013880 return 0;
13881}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013882
13883static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13884 struct net_device *dev,
13885 struct cfg80211_update_ft_ies_params *ftie)
13886{
13887 int ret;
13888
13889 vos_ssr_protect(__func__);
13890 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
13891 vos_ssr_unprotect(__func__);
13892
13893 return ret;
13894}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013895#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013896
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013897#ifdef FEATURE_WLAN_SCAN_PNO
13898
13899void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
13900 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
13901{
13902 int ret;
13903 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
13904 hdd_context_t *pHddCtx;
13905
Nirav Shah80830bf2013-12-31 16:35:12 +053013906 ENTER();
13907
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013908 if (NULL == pAdapter)
13909 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013911 "%s: HDD adapter is Null", __func__);
13912 return ;
13913 }
13914
13915 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13916 if (NULL == pHddCtx)
13917 {
13918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13919 "%s: HDD context is Null!!!", __func__);
13920 return ;
13921 }
13922
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013923 spin_lock(&pHddCtx->schedScan_lock);
13924 if (TRUE == pHddCtx->isWiphySuspended)
13925 {
13926 pHddCtx->isSchedScanUpdatePending = TRUE;
13927 spin_unlock(&pHddCtx->schedScan_lock);
13928 hddLog(VOS_TRACE_LEVEL_INFO,
13929 "%s: Update cfg80211 scan database after it resume", __func__);
13930 return ;
13931 }
13932 spin_unlock(&pHddCtx->schedScan_lock);
13933
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013934 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
13935
13936 if (0 > ret)
13937 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
13938
13939 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013940 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13941 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013942}
13943
13944/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013945 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013946 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013947 */
13948static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
13949{
13950 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13951 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013952 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013953 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13954 int status = 0;
13955 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13956
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013957 /* The current firmware design does not allow PNO during any
13958 * active sessions. Hence, determine the active sessions
13959 * and return a failure.
13960 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013961 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
13962 {
13963 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013964 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013965
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013966 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
13967 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
13968 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
13969 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
13970 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053013971 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013972 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013973 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013974 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013975 }
13976 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13977 pAdapterNode = pNext;
13978 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013979 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013980}
13981
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013982void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
13983{
13984 hdd_adapter_t *pAdapter = callbackContext;
13985 hdd_context_t *pHddCtx;
13986
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013987 ENTER();
13988
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013989 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
13990 {
13991 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13992 FL("Invalid adapter or adapter has invalid magic"));
13993 return;
13994 }
13995
13996 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13997 if (0 != wlan_hdd_validate_context(pHddCtx))
13998 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013999 return;
14000 }
14001
c_hpothub53c45d2014-08-18 16:53:14 +053014002 if (VOS_STATUS_SUCCESS != status)
14003 {
14004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014005 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053014006 pHddCtx->isPnoEnable = FALSE;
14007 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014008
14009 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
14010 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014011 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014012}
14013
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014014/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014015 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
14016 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014017 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014018static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014019 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14020{
14021 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014022 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014023 hdd_context_t *pHddCtx;
14024 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014025 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053014026 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
14027 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014028 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14029 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014030 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014031 hdd_config_t *pConfig = NULL;
14032 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014033
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014034 ENTER();
14035
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014036 if (NULL == pAdapter)
14037 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014038 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014039 "%s: HDD adapter is Null", __func__);
14040 return -ENODEV;
14041 }
14042
14043 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014044 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014045
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014046 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014047 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014048 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014049 }
14050
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014051 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014052 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14053 if (NULL == hHal)
14054 {
14055 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14056 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014057 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014058 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053014059 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014060 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053014061 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014062 {
14063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14064 "%s: aborting the existing scan is unsuccessfull", __func__);
14065 return -EBUSY;
14066 }
14067
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014068 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014069 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014071 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014072 return -EBUSY;
14073 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014074
c_hpothu37f21312014-04-09 21:49:54 +053014075 if (TRUE == pHddCtx->isPnoEnable)
14076 {
14077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14078 FL("already PNO is enabled"));
14079 return -EBUSY;
14080 }
c_hpothu225aa7c2014-10-22 17:45:13 +053014081
14082 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
14083 {
14084 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14085 "%s: abort ROC failed ", __func__);
14086 return -EBUSY;
14087 }
14088
c_hpothu37f21312014-04-09 21:49:54 +053014089 pHddCtx->isPnoEnable = TRUE;
14090
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014091 pnoRequest.enable = 1; /*Enable PNO */
14092 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014093
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014094 if (( !pnoRequest.ucNetworksCount ) ||
14095 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014096 {
14097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014098 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014099 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014100 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014101 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014102 goto error;
14103 }
14104
14105 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
14106 {
14107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014108 "%s: Incorrect number of channels %d",
14109 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014110 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014111 goto error;
14112 }
14113
14114 /* Framework provides one set of channels(all)
14115 * common for all saved profile */
14116 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14117 channels_allowed, &num_channels_allowed))
14118 {
14119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14120 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014121 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014122 goto error;
14123 }
14124 /* Checking each channel against allowed channel list */
14125 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053014126 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014127 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014128 char chList [(request->n_channels*5)+1];
14129 int len;
14130 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014131 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014132 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014133 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014134 if (request->channels[i]->hw_value == channels_allowed[indx])
14135 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014136 if ((!pConfig->enableDFSPnoChnlScan) &&
14137 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
14138 {
14139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14140 "%s : Dropping DFS channel : %d",
14141 __func__,channels_allowed[indx]);
14142 num_ignore_dfs_ch++;
14143 break;
14144 }
14145
Nirav Shah80830bf2013-12-31 16:35:12 +053014146 valid_ch[num_ch++] = request->channels[i]->hw_value;
14147 len += snprintf(chList+len, 5, "%d ",
14148 request->channels[i]->hw_value);
14149 break ;
14150 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014151 }
14152 }
Nirav Shah80830bf2013-12-31 16:35:12 +053014153 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014154
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014155 /*If all channels are DFS and dropped, then ignore the PNO request*/
14156 if (num_ignore_dfs_ch == request->n_channels)
14157 {
14158 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14159 "%s : All requested channels are DFS channels", __func__);
14160 ret = -EINVAL;
14161 goto error;
14162 }
14163 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014164
14165 pnoRequest.aNetworks =
14166 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14167 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014168 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014169 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14170 FL("failed to allocate memory aNetworks %u"),
14171 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14172 goto error;
14173 }
14174 vos_mem_zero(pnoRequest.aNetworks,
14175 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14176
14177 /* Filling per profile params */
14178 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
14179 {
14180 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014181 request->match_sets[i].ssid.ssid_len;
14182
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014183 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
14184 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014185 {
14186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014187 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014188 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014189 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014190 goto error;
14191 }
14192
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014193 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014194 request->match_sets[i].ssid.ssid,
14195 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014196 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14197 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014198 i, pnoRequest.aNetworks[i].ssId.ssId);
14199 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
14200 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
14201 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014202
14203 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014204 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
14205 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014206
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014207 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014208 }
14209
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014210 for (i = 0; i < request->n_ssids; i++)
14211 {
14212 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014213 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014214 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014215 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014216 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014217 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014218 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014219 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014220 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014221 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014222 break;
14223 }
14224 j++;
14225 }
14226 }
14227 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14228 "Number of hidden networks being Configured = %d",
14229 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080014231 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014232
14233 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14234 if (pnoRequest.p24GProbeTemplate == NULL)
14235 {
14236 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14237 FL("failed to allocate memory p24GProbeTemplate %u"),
14238 SIR_PNO_MAX_PB_REQ_SIZE);
14239 goto error;
14240 }
14241
14242 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14243 if (pnoRequest.p5GProbeTemplate == NULL)
14244 {
14245 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14246 FL("failed to allocate memory p5GProbeTemplate %u"),
14247 SIR_PNO_MAX_PB_REQ_SIZE);
14248 goto error;
14249 }
14250
14251 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14252 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14253
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053014254 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
14255 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014256 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014257 pnoRequest.us24GProbeTemplateLen = request->ie_len;
14258 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
14259 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014260
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014261 pnoRequest.us5GProbeTemplateLen = request->ie_len;
14262 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
14263 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014264 }
14265
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014266 /* Driver gets only one time interval which is hardcoded in
14267 * supplicant for 10000ms. Taking power consumption into account 6 timers
14268 * will be used, Timervalue is increased exponentially i.e 10,20,40,
14269 * 80,160,320 secs. And number of scan cycle for each timer
14270 * is configurable through INI param gPNOScanTimerRepeatValue.
14271 * If it is set to 0 only one timer will be used and PNO scan cycle
14272 * will be repeated after each interval specified by supplicant
14273 * till PNO is disabled.
14274 */
14275 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014276 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014277 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014278 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014279 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
14280
14281 tempInterval = (request->interval)/1000;
14282 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14283 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
14284 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014285 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014286 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014287 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014288 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014289 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014290 tempInterval *= 2;
14291 }
14292 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014293 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014294
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014295 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014296
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014297 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014298 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
14299 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014300 pAdapter->pno_req_status = 0;
14301
Nirav Shah80830bf2013-12-31 16:35:12 +053014302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14303 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014304 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
14305 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053014306
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014307 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014308 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014309 hdd_cfg80211_sched_scan_done_callback, pAdapter);
14310 if (eHAL_STATUS_SUCCESS != status)
14311 {
14312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014313 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014314 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014315 goto error;
14316 }
14317
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014318 ret = wait_for_completion_timeout(
14319 &pAdapter->pno_comp_var,
14320 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
14321 if (0 >= ret)
14322 {
14323 // Did not receive the response for PNO enable in time.
14324 // Assuming the PNO enable was success.
14325 // Returning error from here, because we timeout, results
14326 // in side effect of Wifi (Wifi Setting) not to work.
14327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14328 FL("Timed out waiting for PNO to be Enabled"));
14329 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014330 }
14331
14332 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053014333 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014334
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014335error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014336 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14337 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053014338 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014339 if (pnoRequest.aNetworks)
14340 vos_mem_free(pnoRequest.aNetworks);
14341 if (pnoRequest.p24GProbeTemplate)
14342 vos_mem_free(pnoRequest.p24GProbeTemplate);
14343 if (pnoRequest.p5GProbeTemplate)
14344 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014345
14346 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014347 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014348}
14349
14350/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014351 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
14352 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014353 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014354static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
14355 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14356{
14357 int ret;
14358
14359 vos_ssr_protect(__func__);
14360 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
14361 vos_ssr_unprotect(__func__);
14362
14363 return ret;
14364}
14365
14366/*
14367 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
14368 * Function to disable PNO
14369 */
14370static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014371 struct net_device *dev)
14372{
14373 eHalStatus status = eHAL_STATUS_FAILURE;
14374 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14375 hdd_context_t *pHddCtx;
14376 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014377 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014378 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014379
14380 ENTER();
14381
14382 if (NULL == pAdapter)
14383 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014385 "%s: HDD adapter is Null", __func__);
14386 return -ENODEV;
14387 }
14388
14389 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014390
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014391 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014392 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014393 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014394 "%s: HDD context is Null", __func__);
14395 return -ENODEV;
14396 }
14397
14398 /* The return 0 is intentional when isLogpInProgress and
14399 * isLoadUnloadInProgress. We did observe a crash due to a return of
14400 * failure in sched_scan_stop , especially for a case where the unload
14401 * of the happens at the same time. The function __cfg80211_stop_sched_scan
14402 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
14403 * success. If it returns a failure , then its next invocation due to the
14404 * clean up of the second interface will have the dev pointer corresponding
14405 * to the first one leading to a crash.
14406 */
14407 if (pHddCtx->isLogpInProgress)
14408 {
14409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14410 "%s: LOGP in Progress. Ignore!!!", __func__);
14411 return ret;
14412 }
14413
Mihir Shete18156292014-03-11 15:38:30 +053014414 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014415 {
14416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14417 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14418 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014419 }
14420
14421 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14422 if (NULL == hHal)
14423 {
14424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14425 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014426 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014427 }
14428
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014429 pnoRequest.enable = 0; /* Disable PNO */
14430 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014431
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014432 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014433 pAdapter->sessionId,
14434 NULL, pAdapter);
14435 if (eHAL_STATUS_SUCCESS != status)
14436 {
14437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14438 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014439 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014440 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014441 }
c_hpothu37f21312014-04-09 21:49:54 +053014442 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014443
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014444error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014445 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014446 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014447
14448 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014449 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014450}
14451
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014452/*
14453 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
14454 * NL interface to disable PNO
14455 */
14456static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
14457 struct net_device *dev)
14458{
14459 int ret;
14460
14461 vos_ssr_protect(__func__);
14462 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
14463 vos_ssr_unprotect(__func__);
14464
14465 return ret;
14466}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014467#endif /*FEATURE_WLAN_SCAN_PNO*/
14468
14469
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014470#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014471#if TDLS_MGMT_VERSION2
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014472static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014473 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014474 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
14475#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014476static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014477 u8 *peer, u8 action_code, u8 dialog_token,
14478 u16 status_code, const u8 *buf, size_t len)
14479#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014480{
14481
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014482 hdd_adapter_t *pAdapter;
14483 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014484 u8 peerMac[6];
14485 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070014486 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080014487 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070014488 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014489 int ret;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014490#if !(TDLS_MGMT_VERSION2)
14491 u32 peer_capability = 0;
14492#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014493 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014494
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014495 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14496 if (NULL == pAdapter)
14497 {
14498 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14499 "%s: Adapter is NULL",__func__);
14500 return -EINVAL;
14501 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014502 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14503 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
14504 pAdapter->sessionId, action_code));
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014505 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014506 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014507 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014509 "Invalid arguments");
14510 return -EINVAL;
14511 }
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014512 if (pHddCtx->isLogpInProgress)
14513 {
14514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14515 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053014516 wlan_hdd_tdls_set_link_status(pAdapter,
14517 peer,
14518 eTDLS_LINK_IDLE,
14519 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014520 return -EBUSY;
14521 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014522 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
14523 {
14524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14525 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14526 return -EAGAIN;
14527 }
Hoonki Lee27511902013-03-14 18:19:06 -070014528 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014529 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070014531 "%s: TDLS mode is disabled OR not enabled in FW."
14532 MAC_ADDRESS_STR " action %d declined.",
14533 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014534 return -ENOTSUPP;
14535 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014536
Hoonki Lee27511902013-03-14 18:19:06 -070014537 /* other than teardown frame, other mgmt frames are not sent if disabled */
14538 if (SIR_MAC_TDLS_TEARDOWN != action_code)
14539 {
14540 /* if tdls_mode is disabled to respond to peer's request */
14541 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
14542 {
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: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014545 " TDLS mode is disabled. action %d declined.",
14546 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070014547
14548 return -ENOTSUPP;
14549 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014550
14551 if (vos_max_concurrent_connections_reached())
14552 {
14553 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14554 return -EINVAL;
14555 }
Hoonki Lee27511902013-03-14 18:19:06 -070014556 }
14557
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014558 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
14559 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014560 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014561 {
14562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014563 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014564 " TDLS setup is ongoing. action %d declined.",
14565 __func__, MAC_ADDR_ARRAY(peer), action_code);
14566 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014567 }
14568 }
14569
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014570 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
14571 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080014572 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014573 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14574 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014575 {
14576 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
14577 we return error code at 'add_station()'. Hence we have this
14578 check again in addtion to add_station().
14579 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014580 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014581 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14583 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014584 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
14585 __func__, MAC_ADDR_ARRAY(peer), action_code,
14586 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053014587 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080014588 }
14589 else
14590 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014591 /* maximum reached. tweak to send error code to peer and return
14592 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014593 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14595 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014596 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
14597 __func__, MAC_ADDR_ARRAY(peer), status_code,
14598 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070014599 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014600 /* fall through to send setup resp with failure status
14601 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014602 }
14603 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014604 else
14605 {
14606 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014607 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014608 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014609 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014610 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014611 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
14612 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014613 return -EPERM;
14614 }
14615 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014616 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014617 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014618
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014620 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014621 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
14622 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014623
Hoonki Leea34dd892013-02-05 22:56:02 -080014624 /*Except teardown responder will not be used so just make 0*/
14625 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014626 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080014627 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014628
14629 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014630 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014631
14632 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
14633 responder = pTdlsPeer->is_responder;
14634 else
Hoonki Leea34dd892013-02-05 22:56:02 -080014635 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014637 "%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 -070014638 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
14639 dialog_token, status_code, len);
14640 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080014641 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014642 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014643
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014644 /* For explicit trigger of DIS_REQ come out of BMPS for
14645 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070014646 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014647 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
14648 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070014649 {
14650 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
14651 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014653 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070014654 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
14655 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014656 if (SIR_MAC_TDLS_DIS_REQ != action_code)
14657 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070014658 }
14659
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014660 /* make sure doesn't call send_mgmt() while it is pending */
14661 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
14662 {
14663 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014664 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014665 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014666 ret = -EBUSY;
14667 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014668 }
14669
14670 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014671 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
14672
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014673 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053014674 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014675
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014676 if (VOS_STATUS_SUCCESS != status)
14677 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14679 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014680 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014681 ret = -EINVAL;
14682 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014683 }
14684
Hoonki Leed37cbb32013-04-20 00:31:14 -070014685 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
14686 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
14687
14688 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014689 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070014690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014691 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070014692 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014693 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080014694
14695 if (pHddCtx->isLogpInProgress)
14696 {
14697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14698 "%s: LOGP in Progress. Ignore!!!", __func__);
14699 return -EAGAIN;
14700 }
14701
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014702 ret = -EINVAL;
14703 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014704 }
14705
Gopichand Nakkala05922802013-03-14 12:23:19 -070014706 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070014707 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014708 ret = max_sta_failed;
14709 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070014710 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014711
Hoonki Leea34dd892013-02-05 22:56:02 -080014712 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
14713 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014714 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014715 }
14716 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
14717 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014718 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014719 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014720
14721 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014722
14723tx_failed:
14724 /* add_station will be called before sending TDLS_SETUP_REQ and
14725 * TDLS_SETUP_RSP and as part of add_station driver will enable
14726 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
14727 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
14728 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
14729 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
14730 */
14731
14732 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
14733 (SIR_MAC_TDLS_SETUP_RSP == action_code))
14734 wlan_hdd_tdls_check_bmps(pAdapter);
14735 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014736}
14737
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014738#if TDLS_MGMT_VERSION2
14739static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14740 u8 *peer, u8 action_code, u8 dialog_token,
14741 u16 status_code, u32 peer_capability,
14742 const u8 *buf, size_t len)
14743#else
14744static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14745 u8 *peer, u8 action_code, u8 dialog_token,
14746 u16 status_code, const u8 *buf, size_t len)
14747#endif
14748{
14749 int ret;
14750
14751 vos_ssr_protect(__func__);
14752#if TDLS_MGMT_VERSION2
14753 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14754 status_code, peer_capability, buf, len);
14755#else
14756 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14757 status_code, buf, len);
14758#endif
14759 vos_ssr_unprotect(__func__);
14760
14761 return ret;
14762}
Atul Mittal115287b2014-07-08 13:26:33 +053014763
14764int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
14765 u8 *peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014766 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053014767 cfg80211_exttdls_callback callback)
14768{
14769
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014770 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053014771 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014772 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053014773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14774 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
14775 __func__, MAC_ADDR_ARRAY(peer));
14776
14777 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14778 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14779
14780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14781 " %s TDLS External control and Implicit Trigger not enabled ",
14782 __func__);
14783 return -ENOTSUPP;
14784 }
14785
14786 /* To cater the requirement of establishing the TDLS link
14787 * irrespective of the data traffic , get an entry of TDLS peer.
14788 */
14789 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
14790 if (pTdlsPeer == NULL) {
14791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14792 "%s: peer " MAC_ADDRESS_STR " not existing",
14793 __func__, MAC_ADDR_ARRAY(peer));
14794 return -EINVAL;
14795 }
14796
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053014797 /* check FW TDLS Off Channel capability */
14798 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
14799 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014800 {
14801 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
14802 pTdlsPeer->peerParams.global_operating_class =
14803 tdls_peer_params->global_operating_class;
14804 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
14805 pTdlsPeer->peerParams.min_bandwidth_kbps =
14806 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014807 /* check configured channel is valid, non dfs and
14808 * not current operating channel */
14809 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
14810 tdls_peer_params->channel)) &&
14811 (pHddStaCtx) &&
14812 (tdls_peer_params->channel !=
14813 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014814 {
14815 pTdlsPeer->isOffChannelConfigured = TRUE;
14816 }
14817 else
14818 {
14819 pTdlsPeer->isOffChannelConfigured = FALSE;
14820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14821 "%s: Configured Tdls Off Channel is not valid", __func__);
14822
14823 }
14824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014825 "%s: tdls_off_channel %d isOffChannelConfigured %d "
14826 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014827 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014828 pTdlsPeer->isOffChannelConfigured,
14829 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014830 }
14831 else
14832 {
14833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053014834 "%s: TDLS off channel FW capability %d or "
14835 "Invalid TDLS Peer Params", __func__,
14836 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014837 }
14838
Atul Mittal115287b2014-07-08 13:26:33 +053014839 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
14840
14841 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14842 " %s TDLS Add Force Peer Failed",
14843 __func__);
14844 return -EINVAL;
14845 }
14846 /*EXT TDLS*/
14847
14848 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
14849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14850 " %s TDLS set callback Failed",
14851 __func__);
14852 return -EINVAL;
14853 }
14854
14855 return(0);
14856
14857}
14858
14859int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
14860{
14861
14862 hddTdlsPeer_t *pTdlsPeer;
14863 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14865 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
14866 __func__, MAC_ADDR_ARRAY(peer));
14867
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014868 if (0 != wlan_hdd_validate_context(pHddCtx)) {
14869 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
14870 return -EINVAL;
14871 }
14872
Atul Mittal115287b2014-07-08 13:26:33 +053014873 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14874 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14875
14876 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14877 " %s TDLS External control and Implicit Trigger not enabled ",
14878 __func__);
14879 return -ENOTSUPP;
14880 }
14881
14882
14883 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14884
14885 if ( NULL == pTdlsPeer ) {
14886 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
14887 " peer not exsting",
14888 __func__, MAC_ADDR_ARRAY(peer));
14889 return -EINVAL;
14890 }
14891 else {
14892 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
14893 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014894 /* if channel switch is configured, reset
14895 the channel for this peer */
14896 if (TRUE == pTdlsPeer->isOffChannelConfigured)
14897 {
14898 pTdlsPeer->peerParams.channel = 0;
14899 pTdlsPeer->isOffChannelConfigured = FALSE;
14900 }
Atul Mittal115287b2014-07-08 13:26:33 +053014901 }
14902
14903 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
14904 return -EINVAL;
14905
14906 /*EXT TDLS*/
14907
14908 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
14909
14910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14911 " %s TDLS set callback Failed",
14912 __func__);
14913 return -EINVAL;
14914 }
14915 return(0);
14916
14917}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014918static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014919 u8 *peer, enum nl80211_tdls_operation oper)
14920{
14921 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14922 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014923 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014924 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014925
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014926 ENTER();
14927
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014928 if (!pAdapter) {
14929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
14930 return -EINVAL;
14931 }
14932
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014933 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14934 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
14935 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014936 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014937 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014939 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014940 return -EINVAL;
14941 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014942
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014943 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014944 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014945 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014946 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014947 }
14948
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014949
14950 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014951 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014952 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014953 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014954 "TDLS Disabled in INI OR not enabled in FW. "
14955 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014956 return -ENOTSUPP;
14957 }
14958
14959 switch (oper) {
14960 case NL80211_TDLS_ENABLE_LINK:
14961 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014962 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014963 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014964 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053014965 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014966 tANI_U16 numCurrTdlsPeers = 0;
14967 hddTdlsPeer_t *connPeer = NULL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014968
Sunil Dutt41de4e22013-11-14 18:09:02 +053014969 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053014970 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053014971 if ( NULL == pTdlsPeer ) {
14972 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
14973 " (oper %d) not exsting. ignored",
14974 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
14975 return -EINVAL;
14976 }
14977
14978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14979 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
14980 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
14981 "NL80211_TDLS_ENABLE_LINK");
14982
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070014983 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
14984 {
14985 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
14986 MAC_ADDRESS_STR " failed",
14987 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
14988 return -EINVAL;
14989 }
14990
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014991 /* TDLS Off Channel, Disable tdls channel switch,
14992 when there are more than one tdls link */
14993 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14994 if (numCurrTdlsPeers == 1)
14995 {
14996 /* get connected peer and send disable tdls off chan */
14997 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
14998 if (connPeer && (connPeer->isOffChannelConfigured == TRUE))
14999 {
15000 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15001 "%s: More then one peer connected, Disable "
15002 "TDLS channel switch", __func__);
15003
15004 sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
15005 pAdapter->sessionId,
15006 connPeer->peerMac,
15007 connPeer->peerParams.channel,
15008 TDLS_OFF_CHANNEL_BW_OFFSET,
15009 TDLS_CHANNEL_SWITCH_DISABLE);
15010 }
15011 else
15012 {
15013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15014 "%s: No TDLS Connected Peer or "
15015 "isOffChannelConfigured %d",
15016 __func__,
15017 (connPeer ? connPeer->isOffChannelConfigured : -1));
15018 }
15019 }
15020
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015021 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015022 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015023 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053015024
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015025 if (0 != wlan_hdd_tdls_get_link_establish_params(
15026 pAdapter, peer,&tdlsLinkEstablishParams)) {
15027 return -EINVAL;
15028 }
15029 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015030
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015031 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
15032 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
15033 /* Send TDLS peer UAPSD capabilities to the firmware and
15034 * register with the TL on after the response for this operation
15035 * is received .
15036 */
15037 ret = wait_for_completion_interruptible_timeout(
15038 &pAdapter->tdls_link_establish_req_comp,
15039 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
15040 if (ret <= 0)
15041 {
15042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15043 "%s: Link Establish Request Faled Status %ld",
15044 __func__, ret);
15045 return -EINVAL;
15046 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015047 }
Atul Mittal115287b2014-07-08 13:26:33 +053015048 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15049 eTDLS_LINK_CONNECTED,
15050 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015051 staDesc.ucSTAId = pTdlsPeer->staId;
15052 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
15053 WLANTL_UpdateTdlsSTAClient(pHddCtx->pvosContext,
15054 &staDesc);
15055
15056
Gopichand Nakkala471708b2013-06-04 20:03:01 +053015057 /* Mark TDLS client Authenticated .*/
15058 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
15059 pTdlsPeer->staId,
15060 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015061 if (VOS_STATUS_SUCCESS == status)
15062 {
Hoonki Lee14621352013-04-16 17:51:19 -070015063 if (pTdlsPeer->is_responder == 0)
15064 {
15065 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
15066
15067 wlan_hdd_tdls_timer_restart(pAdapter,
15068 &pTdlsPeer->initiatorWaitTimeoutTimer,
15069 WAIT_TIME_TDLS_INITIATOR);
15070 /* suspend initiator TX until it receives direct packet from the
15071 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
15072 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15073 &staId, NULL);
15074 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015075 wlan_hdd_tdls_increment_peer_count(pAdapter);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015076
15077 /* TDLS Off Channel, Enable tdls channel switch,
15078 when their is only one tdls link and it supports */
15079 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15080 if ((numCurrTdlsPeers == 1) &&
15081 (TRUE == pTdlsPeer->isOffChannelSupported) &&
15082 (TRUE == pTdlsPeer->isOffChannelConfigured))
15083 {
15084 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15085 "%s: Send TDLS channel switch request for channel %d",
15086 __func__, pTdlsPeer->peerParams.channel);
15087 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
15088 pAdapter->sessionId,
15089 pTdlsPeer->peerMac,
15090 pTdlsPeer->peerParams.channel,
15091 TDLS_OFF_CHANNEL_BW_OFFSET,
15092 TDLS_CHANNEL_SWITCH_ENABLE);
15093 }
15094 else
15095 {
15096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15097 "%s: TDLS channel switch request not sent"
15098 " numCurrTdlsPeers %d "
15099 "isOffChannelSupported %d "
15100 "isOffChannelConfigured %d",
15101 __func__, numCurrTdlsPeers,
15102 pTdlsPeer->isOffChannelSupported,
15103 pTdlsPeer->isOffChannelConfigured);
15104 }
15105
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015106 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015107 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015108
15109 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015110 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
15111 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015112 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015113 int ac;
15114 uint8 ucAc[4] = { WLANTL_AC_VO,
15115 WLANTL_AC_VI,
15116 WLANTL_AC_BK,
15117 WLANTL_AC_BE };
15118 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
15119 for(ac=0; ac < 4; ac++)
15120 {
15121 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15122 pTdlsPeer->staId, ucAc[ac],
15123 tlTid[ac], tlTid[ac], 0, 0,
15124 WLANTL_BI_DIR );
15125 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015126 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015127 }
15128
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015129 }
15130 break;
15131 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080015132 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015133 tANI_U16 numCurrTdlsPeers = 0;
15134 hddTdlsPeer_t *connPeer = NULL;
15135
Sunil Dutt41de4e22013-11-14 18:09:02 +053015136 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15137
15138 if ( NULL == pTdlsPeer ) {
15139 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15140 " (oper %d) not exsting. ignored",
15141 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15142 return -EINVAL;
15143 }
15144
15145 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15146 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15147 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15148 "NL80211_TDLS_DISABLE_LINK");
15149
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015150 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080015151 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015152 long status;
15153
Atul Mittal271a7652014-09-12 13:18:22 +053015154
15155 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15156 eTDLS_LINK_TEARING,
15157 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
15158 eTDLS_LINK_UNSPECIFIED:
15159 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015160 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
15161
Lee Hoonkic1262f22013-01-24 21:59:00 -080015162 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
15163 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015164
15165 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
15166 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053015167 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053015168 eTDLS_LINK_IDLE,
15169 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015170 if (status <= 0)
15171 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15173 "%s: Del station failed status %ld",
15174 __func__, status);
15175 return -EPERM;
15176 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015177
15178 /* TDLS Off Channel, Enable tdls channel switch,
15179 when their is only one tdls link and it supports */
15180 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15181 if (numCurrTdlsPeers == 1)
15182 {
15183 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
15184 if ((connPeer) &&
15185 (connPeer->isOffChannelSupported == TRUE) &&
15186 (connPeer->isOffChannelConfigured == TRUE))
15187 {
15188 sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
15189 pAdapter->sessionId,
15190 connPeer->peerMac,
15191 connPeer->peerParams.channel,
15192 TDLS_OFF_CHANNEL_BW_OFFSET,
15193 TDLS_CHANNEL_SWITCH_ENABLE);
15194 }
15195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15196 "%s: TDLS channel switch "
15197 "isOffChannelSupported %d "
15198 "isOffChannelConfigured %d",
15199 __func__,
15200 (connPeer ? connPeer->isOffChannelSupported : -1),
15201 (connPeer ? connPeer->isOffChannelConfigured : -1));
15202 }
15203 else
15204 {
15205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15206 "%s: TDLS channel switch request not sent "
15207 "numCurrTdlsPeers %d ",
15208 __func__, numCurrTdlsPeers);
15209 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015210 }
15211 else
15212 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15214 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080015215 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015216 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015217 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015218 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015219 {
Atul Mittal115287b2014-07-08 13:26:33 +053015220 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015221
Atul Mittal115287b2014-07-08 13:26:33 +053015222 if (0 != status)
15223 {
15224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15225 "%s: Error in TDLS Teardown", __func__);
15226 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015227 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053015228 break;
15229 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015230 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015231 {
Atul Mittal115287b2014-07-08 13:26:33 +053015232 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
15233 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015234 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053015235 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015236
Atul Mittal115287b2014-07-08 13:26:33 +053015237 if (0 != status)
15238 {
15239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15240 "%s: Error in TDLS Setup", __func__);
15241 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053015242 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053015243 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015244 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015245 case NL80211_TDLS_DISCOVERY_REQ:
15246 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15248 "%s: We don't support in-driver setup/teardown/discovery "
15249 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015250 return -ENOTSUPP;
15251 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015252 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15253 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015254 return -ENOTSUPP;
15255 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015256
15257 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015258 return 0;
15259}
Chilam NG571c65a2013-01-19 12:27:36 +053015260
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015261static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
15262 u8 *peer, enum nl80211_tdls_operation oper)
15263{
15264 int ret;
15265
15266 vos_ssr_protect(__func__);
15267 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
15268 vos_ssr_unprotect(__func__);
15269
15270 return ret;
15271}
15272
Chilam NG571c65a2013-01-19 12:27:36 +053015273int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
15274 struct net_device *dev, u8 *peer)
15275{
Arif Hussaina7c8e412013-11-20 11:06:42 -080015276 hddLog(VOS_TRACE_LEVEL_INFO,
15277 "tdls send discover req: "MAC_ADDRESS_STR,
15278 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053015279
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015280#if TDLS_MGMT_VERSION2
15281 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15282 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15283#else
Chilam NG571c65a2013-01-19 12:27:36 +053015284 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15285 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015286#endif
Chilam NG571c65a2013-01-19 12:27:36 +053015287}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015288#endif
15289
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015290#ifdef WLAN_FEATURE_GTK_OFFLOAD
15291/*
15292 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
15293 * Callback rountine called upon receiving response for
15294 * get offload info
15295 */
15296void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
15297 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
15298{
15299
15300 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015301 tANI_U8 tempReplayCounter[8];
15302 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015303
15304 ENTER();
15305
15306 if (NULL == pAdapter)
15307 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053015308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015309 "%s: HDD adapter is Null", __func__);
15310 return ;
15311 }
15312
15313 if (NULL == pGtkOffloadGetInfoRsp)
15314 {
15315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15316 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
15317 return ;
15318 }
15319
15320 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
15321 {
15322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15323 "%s: wlan Failed to get replay counter value",
15324 __func__);
15325 return ;
15326 }
15327
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015328 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15329 /* Update replay counter */
15330 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
15331 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15332
15333 {
15334 /* changing from little to big endian since supplicant
15335 * works on big endian format
15336 */
15337 int i;
15338 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15339
15340 for (i = 0; i < 8; i++)
15341 {
15342 tempReplayCounter[7-i] = (tANI_U8)p[i];
15343 }
15344 }
15345
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015346 /* Update replay counter to NL */
15347 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015348 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015349}
15350
15351/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015352 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015353 * This function is used to offload GTK rekeying job to the firmware.
15354 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015355int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015356 struct cfg80211_gtk_rekey_data *data)
15357{
15358 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15359 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15360 hdd_station_ctx_t *pHddStaCtx;
15361 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015362 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015363 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015364 eHalStatus status = eHAL_STATUS_FAILURE;
15365
15366 ENTER();
15367
15368 if (NULL == pAdapter)
15369 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015371 "%s: HDD adapter is Null", __func__);
15372 return -ENODEV;
15373 }
15374
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015375 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15376 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
15377 pAdapter->sessionId, pAdapter->device_mode));
15378
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015379 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015380 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015381 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015382 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015383 }
15384
15385 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15386 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15387 if (NULL == hHal)
15388 {
15389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15390 "%s: HAL context is Null!!!", __func__);
15391 return -EAGAIN;
15392 }
15393
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015394 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
15395 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
15396 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
15397 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015398 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015399 {
15400 /* changing from big to little endian since driver
15401 * works on little endian format
15402 */
15403 tANI_U8 *p =
15404 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
15405 int i;
15406
15407 for (i = 0; i < 8; i++)
15408 {
15409 p[7-i] = data->replay_ctr[i];
15410 }
15411 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015412
15413 if (TRUE == pHddCtx->hdd_wlan_suspended)
15414 {
15415 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015416 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
15417 sizeof (tSirGtkOffloadParams));
15418 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015419 pAdapter->sessionId);
15420
15421 if (eHAL_STATUS_SUCCESS != status)
15422 {
15423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15424 "%s: sme_SetGTKOffload failed, returned %d",
15425 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053015426
15427 /* Need to clear any trace of key value in the memory.
15428 * Thus zero out the memory even though it is local
15429 * variable.
15430 */
15431 vos_mem_zero(&hddGtkOffloadReqParams,
15432 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015433 return status;
15434 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015435 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15436 "%s: sme_SetGTKOffload successfull", __func__);
15437 }
15438 else
15439 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015440 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15441 "%s: wlan not suspended GTKOffload request is stored",
15442 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015443 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015444
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053015445 /* Need to clear any trace of key value in the memory.
15446 * Thus zero out the memory even though it is local
15447 * variable.
15448 */
15449 vos_mem_zero(&hddGtkOffloadReqParams,
15450 sizeof(hddGtkOffloadReqParams));
15451
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015452 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015453 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015454}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015455
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015456int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
15457 struct cfg80211_gtk_rekey_data *data)
15458{
15459 int ret;
15460
15461 vos_ssr_protect(__func__);
15462 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
15463 vos_ssr_unprotect(__func__);
15464
15465 return ret;
15466}
15467#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015468/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015469 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015470 * This function is used to set access control policy
15471 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015472static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15473 struct net_device *dev,
15474 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015475{
15476 int i;
15477 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15478 hdd_hostapd_state_t *pHostapdState;
15479 tsap_Config_t *pConfig;
15480 v_CONTEXT_t pVosContext = NULL;
15481 hdd_context_t *pHddCtx;
15482 int status;
15483
15484 ENTER();
15485
15486 if (NULL == pAdapter)
15487 {
15488 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15489 "%s: HDD adapter is Null", __func__);
15490 return -ENODEV;
15491 }
15492
15493 if (NULL == params)
15494 {
15495 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15496 "%s: params is Null", __func__);
15497 return -EINVAL;
15498 }
15499
15500 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15501 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015502 if (0 != status)
15503 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015504 return status;
15505 }
15506
15507 pVosContext = pHddCtx->pvosContext;
15508 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
15509
15510 if (NULL == pHostapdState)
15511 {
15512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15513 "%s: pHostapdState is Null", __func__);
15514 return -EINVAL;
15515 }
15516
15517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
15518 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
15519
15520 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
15521 {
15522 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
15523
15524 /* default value */
15525 pConfig->num_accept_mac = 0;
15526 pConfig->num_deny_mac = 0;
15527
15528 /**
15529 * access control policy
15530 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
15531 * listed in hostapd.deny file.
15532 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
15533 * listed in hostapd.accept file.
15534 */
15535 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
15536 {
15537 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
15538 }
15539 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
15540 {
15541 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
15542 }
15543 else
15544 {
15545 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15546 "%s:Acl Policy : %d is not supported",
15547 __func__, params->acl_policy);
15548 return -ENOTSUPP;
15549 }
15550
15551 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
15552 {
15553 pConfig->num_accept_mac = params->n_acl_entries;
15554 for (i = 0; i < params->n_acl_entries; i++)
15555 {
15556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15557 "** Add ACL MAC entry %i in WhiletList :"
15558 MAC_ADDRESS_STR, i,
15559 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
15560
15561 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
15562 sizeof(qcmacaddr));
15563 }
15564 }
15565 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
15566 {
15567 pConfig->num_deny_mac = params->n_acl_entries;
15568 for (i = 0; i < params->n_acl_entries; i++)
15569 {
15570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15571 "** Add ACL MAC entry %i in BlackList :"
15572 MAC_ADDRESS_STR, i,
15573 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
15574
15575 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
15576 sizeof(qcmacaddr));
15577 }
15578 }
15579
15580 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
15581 {
15582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15583 "%s: SAP Set Mac Acl fail", __func__);
15584 return -EINVAL;
15585 }
15586 }
15587 else
15588 {
15589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015590 "%s: Invalid device_mode = %s (%d)",
15591 __func__, hdd_device_modetoString(pAdapter->device_mode),
15592 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015593 return -EINVAL;
15594 }
15595
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015596 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015597 return 0;
15598}
15599
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015600static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15601 struct net_device *dev,
15602 const struct cfg80211_acl_data *params)
15603{
15604 int ret;
15605 vos_ssr_protect(__func__);
15606 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
15607 vos_ssr_unprotect(__func__);
15608
15609 return ret;
15610}
15611
Leo Chang9056f462013-08-01 19:21:11 -070015612#ifdef WLAN_NL80211_TESTMODE
15613#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070015614void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070015615(
15616 void *pAdapter,
15617 void *indCont
15618)
15619{
Leo Changd9df8aa2013-09-26 13:32:26 -070015620 tSirLPHBInd *lphbInd;
15621 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053015622 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070015623
15624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070015625 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070015626
c_hpothu73f35e62014-04-18 13:40:08 +053015627 if (pAdapter == NULL)
15628 {
15629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15630 "%s: pAdapter is NULL\n",__func__);
15631 return;
15632 }
15633
Leo Chang9056f462013-08-01 19:21:11 -070015634 if (NULL == indCont)
15635 {
15636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070015637 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070015638 return;
15639 }
15640
c_hpothu73f35e62014-04-18 13:40:08 +053015641 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070015642 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070015643 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053015644 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070015645 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070015646 GFP_ATOMIC);
15647 if (!skb)
15648 {
15649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15650 "LPHB timeout, NL buffer alloc fail");
15651 return;
15652 }
15653
Leo Changac3ba772013-10-07 09:47:04 -070015654 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070015655 {
15656 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15657 "WLAN_HDD_TM_ATTR_CMD put fail");
15658 goto nla_put_failure;
15659 }
Leo Changac3ba772013-10-07 09:47:04 -070015660 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070015661 {
15662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15663 "WLAN_HDD_TM_ATTR_TYPE put fail");
15664 goto nla_put_failure;
15665 }
Leo Changac3ba772013-10-07 09:47:04 -070015666 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070015667 sizeof(tSirLPHBInd), lphbInd))
15668 {
15669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15670 "WLAN_HDD_TM_ATTR_DATA put fail");
15671 goto nla_put_failure;
15672 }
Leo Chang9056f462013-08-01 19:21:11 -070015673 cfg80211_testmode_event(skb, GFP_ATOMIC);
15674 return;
15675
15676nla_put_failure:
15677 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15678 "NLA Put fail");
15679 kfree_skb(skb);
15680
15681 return;
15682}
15683#endif /* FEATURE_WLAN_LPHB */
15684
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015685static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070015686{
15687 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
15688 int err = 0;
15689#ifdef FEATURE_WLAN_LPHB
15690 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070015691 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015692
15693 ENTER();
15694
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015695 err = wlan_hdd_validate_context(pHddCtx);
15696 if (0 != err)
15697 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015698 return err;
15699 }
Leo Chang9056f462013-08-01 19:21:11 -070015700#endif /* FEATURE_WLAN_LPHB */
15701
15702 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
15703 if (err)
15704 {
15705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15706 "%s Testmode INV ATTR", __func__);
15707 return err;
15708 }
15709
15710 if (!tb[WLAN_HDD_TM_ATTR_CMD])
15711 {
15712 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15713 "%s Testmode INV CMD", __func__);
15714 return -EINVAL;
15715 }
15716
15717 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
15718 {
15719#ifdef FEATURE_WLAN_LPHB
15720 /* Low Power Heartbeat configuration request */
15721 case WLAN_HDD_TM_CMD_WLAN_HB:
15722 {
15723 int buf_len;
15724 void *buf;
15725 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080015726 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070015727
15728 if (!tb[WLAN_HDD_TM_ATTR_DATA])
15729 {
15730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15731 "%s Testmode INV DATA", __func__);
15732 return -EINVAL;
15733 }
15734
15735 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
15736 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080015737
15738 hb_params_temp =(tSirLPHBReq *)buf;
15739 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
15740 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
15741 return -EINVAL;
15742
Leo Chang9056f462013-08-01 19:21:11 -070015743 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
15744 if (NULL == hb_params)
15745 {
15746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15747 "%s Request Buffer Alloc Fail", __func__);
15748 return -EINVAL;
15749 }
15750
15751 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070015752 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
15753 hb_params,
15754 wlan_hdd_cfg80211_lphb_ind_handler);
15755 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070015756 {
Leo Changd9df8aa2013-09-26 13:32:26 -070015757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15758 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070015759 vos_mem_free(hb_params);
15760 }
Leo Chang9056f462013-08-01 19:21:11 -070015761 return 0;
15762 }
15763#endif /* FEATURE_WLAN_LPHB */
15764 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15766 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070015767 return -EOPNOTSUPP;
15768 }
15769
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015770 EXIT();
15771 return err;
Leo Chang9056f462013-08-01 19:21:11 -070015772}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015773
15774static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
15775{
15776 int ret;
15777
15778 vos_ssr_protect(__func__);
15779 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
15780 vos_ssr_unprotect(__func__);
15781
15782 return ret;
15783}
Leo Chang9056f462013-08-01 19:21:11 -070015784#endif /* CONFIG_NL80211_TESTMODE */
15785
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015786static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015787 struct net_device *dev,
15788 int idx, struct survey_info *survey)
15789{
15790 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15791 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053015792 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015793 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053015794 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015795 v_S7_t snr,rssi;
15796 int status, i, j, filled = 0;
15797
15798 ENTER();
15799
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015800 if (NULL == pAdapter)
15801 {
15802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15803 "%s: HDD adapter is Null", __func__);
15804 return -ENODEV;
15805 }
15806
15807 if (NULL == wiphy)
15808 {
15809 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15810 "%s: wiphy is Null", __func__);
15811 return -ENODEV;
15812 }
15813
15814 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15815 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015816 if (0 != status)
15817 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015818 return status;
15819 }
15820
Mihir Sheted9072e02013-08-21 17:02:29 +053015821 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15822
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015823 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053015824 0 != pAdapter->survey_idx ||
15825 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015826 {
15827 /* The survey dump ops when implemented completely is expected to
15828 * return a survey of all channels and the ops is called by the
15829 * kernel with incremental values of the argument 'idx' till it
15830 * returns -ENONET. But we can only support the survey for the
15831 * operating channel for now. survey_idx is used to track
15832 * that the ops is called only once and then return -ENONET for
15833 * the next iteration
15834 */
15835 pAdapter->survey_idx = 0;
15836 return -ENONET;
15837 }
15838
15839 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15840
15841 wlan_hdd_get_snr(pAdapter, &snr);
15842 wlan_hdd_get_rssi(pAdapter, &rssi);
15843
15844 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
15845 hdd_wlan_get_freq(channel, &freq);
15846
15847
15848 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
15849 {
15850 if (NULL == wiphy->bands[i])
15851 {
15852 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
15853 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
15854 continue;
15855 }
15856
15857 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
15858 {
15859 struct ieee80211_supported_band *band = wiphy->bands[i];
15860
15861 if (band->channels[j].center_freq == (v_U16_t)freq)
15862 {
15863 survey->channel = &band->channels[j];
15864 /* The Rx BDs contain SNR values in dB for the received frames
15865 * while the supplicant expects noise. So we calculate and
15866 * return the value of noise (dBm)
15867 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
15868 */
15869 survey->noise = rssi - snr;
15870 survey->filled = SURVEY_INFO_NOISE_DBM;
15871 filled = 1;
15872 }
15873 }
15874 }
15875
15876 if (filled)
15877 pAdapter->survey_idx = 1;
15878 else
15879 {
15880 pAdapter->survey_idx = 0;
15881 return -ENONET;
15882 }
15883
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015884 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015885 return 0;
15886}
15887
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015888static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
15889 struct net_device *dev,
15890 int idx, struct survey_info *survey)
15891{
15892 int ret;
15893
15894 vos_ssr_protect(__func__);
15895 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
15896 vos_ssr_unprotect(__func__);
15897
15898 return ret;
15899}
15900
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015901/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015902 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015903 * this is called when cfg80211 driver resume
15904 * driver updates latest sched_scan scan result(if any) to cfg80211 database
15905 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015906int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015907{
15908 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15909 hdd_adapter_t *pAdapter;
15910 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15911 VOS_STATUS status = VOS_STATUS_SUCCESS;
15912
15913 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015914
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015915 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015916 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015917 return 0;
15918 }
15919
15920 spin_lock(&pHddCtx->schedScan_lock);
15921 pHddCtx->isWiphySuspended = FALSE;
15922 if (TRUE != pHddCtx->isSchedScanUpdatePending)
15923 {
15924 spin_unlock(&pHddCtx->schedScan_lock);
15925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15926 "%s: Return resume is not due to PNO indication", __func__);
15927 return 0;
15928 }
15929 // Reset flag to avoid updatating cfg80211 data old results again
15930 pHddCtx->isSchedScanUpdatePending = FALSE;
15931 spin_unlock(&pHddCtx->schedScan_lock);
15932
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015933
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015934 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15935
15936 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15937 {
15938 pAdapter = pAdapterNode->pAdapter;
15939 if ( (NULL != pAdapter) &&
15940 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
15941 {
15942 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015943 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15945 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015946 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015947 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015948 {
15949 /* Acquire wakelock to handle the case where APP's tries to
15950 * suspend immediately after updating the scan results. Whis
15951 * results in app's is in suspended state and not able to
15952 * process the connect request to AP
15953 */
15954 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015955 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015956 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015957
15958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15959 "%s : cfg80211 scan result database updated", __func__);
15960
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015961 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015962 return 0;
15963
15964 }
15965 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15966 pAdapterNode = pNext;
15967 }
15968
15969 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15970 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015971 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015972 return 0;
15973}
15974
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015975int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
15976{
15977 int ret;
15978
15979 vos_ssr_protect(__func__);
15980 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
15981 vos_ssr_unprotect(__func__);
15982
15983 return ret;
15984}
15985
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015986/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015987 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015988 * this is called when cfg80211 driver suspends
15989 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015990int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015991 struct cfg80211_wowlan *wow)
15992{
15993 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015994 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015995
15996 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015997
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015998 ret = wlan_hdd_validate_context(pHddCtx);
15999 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016000 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016001 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016002 }
16003
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016004
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016005 pHddCtx->isWiphySuspended = TRUE;
16006
16007 EXIT();
16008
16009 return 0;
16010}
16011
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016012int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
16013 struct cfg80211_wowlan *wow)
16014{
16015 int ret;
16016
16017 vos_ssr_protect(__func__);
16018 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
16019 vos_ssr_unprotect(__func__);
16020
16021 return ret;
16022}
Jeff Johnson295189b2012-06-20 16:38:30 -070016023/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016024static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070016025{
16026 .add_virtual_intf = wlan_hdd_add_virtual_intf,
16027 .del_virtual_intf = wlan_hdd_del_virtual_intf,
16028 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
16029 .change_station = wlan_hdd_change_station,
16030#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
16031 .add_beacon = wlan_hdd_cfg80211_add_beacon,
16032 .del_beacon = wlan_hdd_cfg80211_del_beacon,
16033 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016034#else
16035 .start_ap = wlan_hdd_cfg80211_start_ap,
16036 .change_beacon = wlan_hdd_cfg80211_change_beacon,
16037 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070016038#endif
16039 .change_bss = wlan_hdd_cfg80211_change_bss,
16040 .add_key = wlan_hdd_cfg80211_add_key,
16041 .get_key = wlan_hdd_cfg80211_get_key,
16042 .del_key = wlan_hdd_cfg80211_del_key,
16043 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016044#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070016045 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016046#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016047 .scan = wlan_hdd_cfg80211_scan,
16048 .connect = wlan_hdd_cfg80211_connect,
16049 .disconnect = wlan_hdd_cfg80211_disconnect,
16050 .join_ibss = wlan_hdd_cfg80211_join_ibss,
16051 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
16052 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
16053 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
16054 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070016055 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
16056 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053016057 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070016058#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16059 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
16060 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
16061 .set_txq_params = wlan_hdd_set_txq_params,
16062#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016063 .get_station = wlan_hdd_cfg80211_get_station,
16064 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
16065 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016066 .add_station = wlan_hdd_cfg80211_add_station,
16067#ifdef FEATURE_WLAN_LFR
16068 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
16069 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
16070 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
16071#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016072#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
16073 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
16074#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016075#ifdef FEATURE_WLAN_TDLS
16076 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
16077 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
16078#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016079#ifdef WLAN_FEATURE_GTK_OFFLOAD
16080 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
16081#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016082#ifdef FEATURE_WLAN_SCAN_PNO
16083 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
16084 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
16085#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016086 .resume = wlan_hdd_cfg80211_resume_wlan,
16087 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016088 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070016089#ifdef WLAN_NL80211_TESTMODE
16090 .testmode_cmd = wlan_hdd_cfg80211_testmode,
16091#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016092 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070016093};
16094