blob: de675e1b0a4e490f40b96e58cdfaf1c88fb39ea0 [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#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
99
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,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530624#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
625 NULL,
626#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800627 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530628 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800629 GFP_KERNEL);
630 if (!vendor_event)
631 {
632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
633 "%s: cfg80211_vendor_event_alloc failed", __func__);
634 return -1;
635 }
636
637 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
638 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
639
640 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
641
642 EXIT();
643 return 0;
644}
645#endif /* FEATURE_WLAN_CH_AVOID */
646
Srinivas Dasari030bad32015-02-18 23:23:54 +0530647/*
648 * FUNCTION: __wlan_hdd_cfg80211_nan_request
649 * This is called when wlan driver needs to send vendor specific
650 * nan request event.
651 */
652static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
653 struct wireless_dev *wdev,
654 const void *data, int data_len)
655{
656 tNanRequestReq nan_req;
657 VOS_STATUS status;
658 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530659 struct net_device *dev = wdev->netdev;
660 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
661 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530662 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
663
664 if (0 == data_len)
665 {
666 hddLog(VOS_TRACE_LEVEL_ERROR,
667 FL("NAN - Invalid Request, length = 0"));
668 return ret_val;
669 }
670
671 if (NULL == data)
672 {
673 hddLog(VOS_TRACE_LEVEL_ERROR,
674 FL("NAN - Invalid Request, data is NULL"));
675 return ret_val;
676 }
677
678 status = wlan_hdd_validate_context(pHddCtx);
679 if (0 != status)
680 {
681 hddLog(VOS_TRACE_LEVEL_ERROR,
682 FL("HDD context is not valid"));
683 return -EINVAL;
684 }
685
686 hddLog(LOG1, FL("Received NAN command"));
687 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
688 (tANI_U8 *)data, data_len);
689
690 /* check the NAN Capability */
691 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
692 {
693 hddLog(VOS_TRACE_LEVEL_ERROR,
694 FL("NAN is not supported by Firmware"));
695 return -EINVAL;
696 }
697
698 nan_req.request_data_len = data_len;
699 nan_req.request_data = data;
700
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530701 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530702 if (VOS_STATUS_SUCCESS == status)
703 {
704 ret_val = 0;
705 }
706 return ret_val;
707}
708
709/*
710 * FUNCTION: wlan_hdd_cfg80211_nan_request
711 * Wrapper to protect the nan vendor command from ssr
712 */
713static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
714 struct wireless_dev *wdev,
715 const void *data, int data_len)
716{
717 int ret;
718
719 vos_ssr_protect(__func__);
720 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
721 vos_ssr_unprotect(__func__);
722
723 return ret;
724}
725
726/*
727 * FUNCTION: wlan_hdd_cfg80211_nan_callback
728 * This is a callback function and it gets called
729 * when we need to report nan response event to
730 * upper layers.
731 */
732static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
733{
734 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
735 struct sk_buff *vendor_event;
736 int status;
737 tSirNanEvent *data;
738
739 ENTER();
740 if (NULL == msg)
741 {
742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
743 FL(" msg received here is null"));
744 return;
745 }
746 data = msg;
747
748 status = wlan_hdd_validate_context(pHddCtx);
749
750 if (0 != status)
751 {
752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
753 FL("HDD context is not valid"));
754 return;
755 }
756
757 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530758#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
759 NULL,
760#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530761 data->event_data_len +
762 NLMSG_HDRLEN,
763 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
764 GFP_KERNEL);
765
766 if (!vendor_event)
767 {
768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
769 FL("cfg80211_vendor_event_alloc failed"));
770 return;
771 }
772 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
773 data->event_data_len, data->event_data))
774 {
775 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
776 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
777 kfree_skb(vendor_event);
778 return;
779 }
780 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
781 EXIT();
782}
783
784/*
785 * FUNCTION: wlan_hdd_cfg80211_nan_init
786 * This function is called to register the callback to sme layer
787 */
788inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
789{
790 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
791}
792
793
Sunil Duttc69bccb2014-05-26 21:30:20 +0530794#ifdef WLAN_FEATURE_LINK_LAYER_STATS
795
796static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
797 struct sk_buff *vendor_event)
798{
799 if (nla_put_u8(vendor_event,
800 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
801 stats->rate.preamble) ||
802 nla_put_u8(vendor_event,
803 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
804 stats->rate.nss) ||
805 nla_put_u8(vendor_event,
806 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
807 stats->rate.bw) ||
808 nla_put_u8(vendor_event,
809 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
810 stats->rate.rateMcsIdx) ||
811 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
812 stats->rate.bitrate ) ||
813 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
814 stats->txMpdu ) ||
815 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
816 stats->rxMpdu ) ||
817 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
818 stats->mpduLost ) ||
819 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
820 stats->retries) ||
821 nla_put_u32(vendor_event,
822 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
823 stats->retriesShort ) ||
824 nla_put_u32(vendor_event,
825 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
826 stats->retriesLong))
827 {
828 hddLog(VOS_TRACE_LEVEL_ERROR,
829 FL("QCA_WLAN_VENDOR_ATTR put fail"));
830 return FALSE;
831 }
832 return TRUE;
833}
834
835static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
836 struct sk_buff *vendor_event)
837{
838 u32 i = 0;
839 struct nlattr *rateInfo;
840 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
841 stats->type) ||
842 nla_put(vendor_event,
843 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
844 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
845 nla_put_u32(vendor_event,
846 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
847 stats->capabilities) ||
848 nla_put_u32(vendor_event,
849 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
850 stats->numRate))
851 {
852 hddLog(VOS_TRACE_LEVEL_ERROR,
853 FL("QCA_WLAN_VENDOR_ATTR put fail"));
854 goto error;
855 }
856
857 rateInfo = nla_nest_start(vendor_event,
858 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530859 if(!rateInfo)
860 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530861 for (i = 0; i < stats->numRate; i++)
862 {
863 struct nlattr *rates;
864 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
865 stats->rateStats +
866 (i * sizeof(tSirWifiRateStat)));
867 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530868 if(!rates)
869 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530870
871 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
872 {
873 hddLog(VOS_TRACE_LEVEL_ERROR,
874 FL("QCA_WLAN_VENDOR_ATTR put fail"));
875 return FALSE;
876 }
877 nla_nest_end(vendor_event, rates);
878 }
879 nla_nest_end(vendor_event, rateInfo);
880
881 return TRUE;
882error:
883 return FALSE;
884}
885
886static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
887 struct sk_buff *vendor_event)
888{
889 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
890 stats->ac ) ||
891 nla_put_u32(vendor_event,
892 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
893 stats->txMpdu ) ||
894 nla_put_u32(vendor_event,
895 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
896 stats->rxMpdu ) ||
897 nla_put_u32(vendor_event,
898 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
899 stats->txMcast ) ||
900 nla_put_u32(vendor_event,
901 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
902 stats->rxMcast ) ||
903 nla_put_u32(vendor_event,
904 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
905 stats->rxAmpdu ) ||
906 nla_put_u32(vendor_event,
907 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
908 stats->txAmpdu ) ||
909 nla_put_u32(vendor_event,
910 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
911 stats->mpduLost )||
912 nla_put_u32(vendor_event,
913 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
914 stats->retries ) ||
915 nla_put_u32(vendor_event,
916 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
917 stats->retriesShort ) ||
918 nla_put_u32(vendor_event,
919 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
920 stats->retriesLong ) ||
921 nla_put_u32(vendor_event,
922 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
923 stats->contentionTimeMin ) ||
924 nla_put_u32(vendor_event,
925 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
926 stats->contentionTimeMax ) ||
927 nla_put_u32(vendor_event,
928 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
929 stats->contentionTimeAvg ) ||
930 nla_put_u32(vendor_event,
931 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
932 stats->contentionNumSamples ))
933 {
934 hddLog(VOS_TRACE_LEVEL_ERROR,
935 FL("QCA_WLAN_VENDOR_ATTR put fail") );
936 return FALSE;
937 }
938 return TRUE;
939}
940
941static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
942 struct sk_buff *vendor_event)
943{
Dino Myclec8f3f332014-07-21 16:48:27 +0530944 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530945 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
946 nla_put(vendor_event,
947 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
948 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
949 nla_put_u32(vendor_event,
950 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
951 stats->state ) ||
952 nla_put_u32(vendor_event,
953 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
954 stats->roaming ) ||
955 nla_put_u32(vendor_event,
956 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
957 stats->capabilities ) ||
958 nla_put(vendor_event,
959 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
960 strlen(stats->ssid), stats->ssid) ||
961 nla_put(vendor_event,
962 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
963 WNI_CFG_BSSID_LEN, stats->bssid) ||
964 nla_put(vendor_event,
965 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
966 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
967 nla_put(vendor_event,
968 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
969 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
970 )
971 {
972 hddLog(VOS_TRACE_LEVEL_ERROR,
973 FL("QCA_WLAN_VENDOR_ATTR put fail") );
974 return FALSE;
975 }
976 return TRUE;
977}
978
Dino Mycle3b9536d2014-07-09 22:05:24 +0530979static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
980 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530981 struct sk_buff *vendor_event)
982{
983 int i = 0;
984 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530985 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
986 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530987 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530988
Sunil Duttc69bccb2014-05-26 21:30:20 +0530989 if (FALSE == put_wifi_interface_info(
990 &pWifiIfaceStat->info,
991 vendor_event))
992 {
993 hddLog(VOS_TRACE_LEVEL_ERROR,
994 FL("QCA_WLAN_VENDOR_ATTR put fail") );
995 return FALSE;
996
997 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530998 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
999 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
1000 if (NULL == pWifiIfaceStatTL)
1001 {
1002 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1003 return FALSE;
1004 }
1005
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301006 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1007 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1008 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1009 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1010
1011 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1012 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1013 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1014 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301015
1016 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1017 {
1018 if (VOS_STATUS_SUCCESS ==
1019 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1020 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1021 {
1022 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1023 * obtained from TL structure
1024 */
1025
1026 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1027 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301028 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1029
Srinivas Dasari98947432014-11-07 19:41:24 +05301030 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1031 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1032 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1033 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1034 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1035 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1036 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1037 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301038
Srinivas Dasari98947432014-11-07 19:41:24 +05301039 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1040 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1041 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1042 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1043 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1044 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1045 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1046 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301047
Srinivas Dasari98947432014-11-07 19:41:24 +05301048 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1049 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1050 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1051 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1052 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1053 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1054 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1055 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301056 }
1057 else
1058 {
1059 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1060 }
1061
Dino Mycle3b9536d2014-07-09 22:05:24 +05301062 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1063 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1064 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1065 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1066 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1067 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1068 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1069 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1070 }
1071 else
1072 {
1073 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1074 }
1075
1076
Sunil Duttc69bccb2014-05-26 21:30:20 +05301077
1078 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301079 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1080 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1081 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301082 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1083 pWifiIfaceStat->beaconRx) ||
1084 nla_put_u32(vendor_event,
1085 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1086 pWifiIfaceStat->mgmtRx) ||
1087 nla_put_u32(vendor_event,
1088 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1089 pWifiIfaceStat->mgmtActionRx) ||
1090 nla_put_u32(vendor_event,
1091 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1092 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301093 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301094 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1095 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301096 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301097 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1098 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301099 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301100 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1101 pWifiIfaceStat->rssiAck))
1102 {
1103 hddLog(VOS_TRACE_LEVEL_ERROR,
1104 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301105 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301106 return FALSE;
1107 }
1108
1109 wmmInfo = nla_nest_start(vendor_event,
1110 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301111 if(!wmmInfo)
1112 {
1113 vos_mem_free(pWifiIfaceStatTL);
1114 return FALSE;
1115 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301116 for (i = 0; i < WIFI_AC_MAX; i++)
1117 {
1118 struct nlattr *wmmStats;
1119 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301120 if(!wmmStats)
1121 {
1122 vos_mem_free(pWifiIfaceStatTL);
1123 return FALSE;
1124 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301125 if (FALSE == put_wifi_wmm_ac_stat(
1126 &pWifiIfaceStat->AccessclassStats[i],
1127 vendor_event))
1128 {
1129 hddLog(VOS_TRACE_LEVEL_ERROR,
1130 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301131 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301132 return FALSE;
1133 }
1134
1135 nla_nest_end(vendor_event, wmmStats);
1136 }
1137 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301138 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301139 return TRUE;
1140}
1141
1142static tSirWifiInterfaceMode
1143 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1144{
1145 switch (deviceMode)
1146 {
1147 case WLAN_HDD_INFRA_STATION:
1148 return WIFI_INTERFACE_STA;
1149 case WLAN_HDD_SOFTAP:
1150 return WIFI_INTERFACE_SOFTAP;
1151 case WLAN_HDD_P2P_CLIENT:
1152 return WIFI_INTERFACE_P2P_CLIENT;
1153 case WLAN_HDD_P2P_GO:
1154 return WIFI_INTERFACE_P2P_GO;
1155 case WLAN_HDD_IBSS:
1156 return WIFI_INTERFACE_IBSS;
1157 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301158 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301159 }
1160}
1161
1162static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1163 tpSirWifiInterfaceInfo pInfo)
1164{
1165 v_U8_t *staMac = NULL;
1166 hdd_station_ctx_t *pHddStaCtx;
1167 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1168 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1169
1170 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1171
1172 vos_mem_copy(pInfo->macAddr,
1173 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1174
1175 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1176 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1177 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1178 {
1179 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1180 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1181 {
1182 pInfo->state = WIFI_DISCONNECTED;
1183 }
1184 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1185 {
1186 hddLog(VOS_TRACE_LEVEL_ERROR,
1187 "%s: Session ID %d, Connection is in progress", __func__,
1188 pAdapter->sessionId);
1189 pInfo->state = WIFI_ASSOCIATING;
1190 }
1191 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1192 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1193 {
1194 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1195 hddLog(VOS_TRACE_LEVEL_ERROR,
1196 "%s: client " MAC_ADDRESS_STR
1197 " is in the middle of WPS/EAPOL exchange.", __func__,
1198 MAC_ADDR_ARRAY(staMac));
1199 pInfo->state = WIFI_AUTHENTICATING;
1200 }
1201 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1202 {
1203 pInfo->state = WIFI_ASSOCIATED;
1204 vos_mem_copy(pInfo->bssid,
1205 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1206 vos_mem_copy(pInfo->ssid,
1207 pHddStaCtx->conn_info.SSID.SSID.ssId,
1208 pHddStaCtx->conn_info.SSID.SSID.length);
1209 //NULL Terminate the string.
1210 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1211 }
1212 }
1213 vos_mem_copy(pInfo->countryStr,
1214 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1215
1216 vos_mem_copy(pInfo->apCountryStr,
1217 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1218
1219 return TRUE;
1220}
1221
1222/*
1223 * hdd_link_layer_process_peer_stats () - This function is called after
1224 * receiving Link Layer Peer statistics from FW.This function converts
1225 * the firmware data to the NL data and sends the same to the kernel/upper
1226 * layers.
1227 */
1228static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1229 v_VOID_t *pData)
1230{
1231 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301232 tpSirWifiPeerStat pWifiPeerStat;
1233 tpSirWifiPeerInfo pWifiPeerInfo;
1234 struct nlattr *peerInfo;
1235 struct sk_buff *vendor_event;
1236 int status, i;
1237
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301238 ENTER();
1239
Sunil Duttc69bccb2014-05-26 21:30:20 +05301240 status = wlan_hdd_validate_context(pHddCtx);
1241 if (0 != status)
1242 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301243 return;
1244 }
1245
1246 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1247
1248 hddLog(VOS_TRACE_LEVEL_INFO,
1249 "LL_STATS_PEER_ALL : numPeers %u",
1250 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301251 /*
1252 * Allocate a size of 4096 for the peer stats comprising
1253 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1254 * sizeof (tSirWifiRateStat).Each field is put with an
1255 * NL attribute.The size of 4096 is considered assuming
1256 * that number of rates shall not exceed beyond 50 with
1257 * the sizeof (tSirWifiRateStat) being 32.
1258 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301259 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1260 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301261 if (!vendor_event)
1262 {
1263 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301264 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301265 __func__);
1266 return;
1267 }
1268 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301269 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1270 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1271 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301272 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1273 pWifiPeerStat->numPeers))
1274 {
1275 hddLog(VOS_TRACE_LEVEL_ERROR,
1276 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1277 kfree_skb(vendor_event);
1278 return;
1279 }
1280
1281 peerInfo = nla_nest_start(vendor_event,
1282 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301283 if(!peerInfo)
1284 {
1285 hddLog(VOS_TRACE_LEVEL_ERROR,
1286 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1287 __func__);
1288 kfree_skb(vendor_event);
1289 return;
1290 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301291
1292 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1293 pWifiPeerStat->peerInfo);
1294
1295 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1296 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301297 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301298 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301299
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301300 if(!peers)
1301 {
1302 hddLog(VOS_TRACE_LEVEL_ERROR,
1303 "%s: peer stats put fail",
1304 __func__);
1305 kfree_skb(vendor_event);
1306 return;
1307 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301308 if (FALSE == put_wifi_peer_info(
1309 pWifiPeerInfo, vendor_event))
1310 {
1311 hddLog(VOS_TRACE_LEVEL_ERROR,
1312 "%s: put_wifi_peer_info put fail", __func__);
1313 kfree_skb(vendor_event);
1314 return;
1315 }
1316
1317 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1318 pWifiPeerStat->peerInfo +
1319 (i * sizeof(tSirWifiPeerInfo)) +
1320 (numRate * sizeof (tSirWifiRateStat)));
1321 nla_nest_end(vendor_event, peers);
1322 }
1323 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301324 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301325 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301326}
1327
1328/*
1329 * hdd_link_layer_process_iface_stats () - This function is called after
1330 * receiving Link Layer Interface statistics from FW.This function converts
1331 * the firmware data to the NL data and sends the same to the kernel/upper
1332 * layers.
1333 */
1334static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1335 v_VOID_t *pData)
1336{
1337 tpSirWifiIfaceStat pWifiIfaceStat;
1338 struct sk_buff *vendor_event;
1339 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1340 int status;
1341
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301342 ENTER();
1343
Sunil Duttc69bccb2014-05-26 21:30:20 +05301344 status = wlan_hdd_validate_context(pHddCtx);
1345 if (0 != status)
1346 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301347 return;
1348 }
1349 /*
1350 * Allocate a size of 4096 for the interface stats comprising
1351 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1352 * assuming that all these fit with in the limit.Please take
1353 * a call on the limit based on the data requirements on
1354 * interface statistics.
1355 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301356 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1357 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301358 if (!vendor_event)
1359 {
1360 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301361 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301362 return;
1363 }
1364
1365 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1366
Dino Mycle3b9536d2014-07-09 22:05:24 +05301367
1368 if (FALSE == hdd_get_interface_info( pAdapter,
1369 &pWifiIfaceStat->info))
1370 {
1371 hddLog(VOS_TRACE_LEVEL_ERROR,
1372 FL("hdd_get_interface_info get fail") );
1373 kfree_skb(vendor_event);
1374 return;
1375 }
1376
1377 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1378 vendor_event))
1379 {
1380 hddLog(VOS_TRACE_LEVEL_ERROR,
1381 FL("put_wifi_iface_stats fail") );
1382 kfree_skb(vendor_event);
1383 return;
1384 }
1385
Sunil Duttc69bccb2014-05-26 21:30:20 +05301386 hddLog(VOS_TRACE_LEVEL_INFO,
1387 "WMI_LINK_STATS_IFACE Data");
1388
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301389 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301390
1391 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301392}
1393
1394/*
1395 * hdd_link_layer_process_radio_stats () - This function is called after
1396 * receiving Link Layer Radio statistics from FW.This function converts
1397 * the firmware data to the NL data and sends the same to the kernel/upper
1398 * layers.
1399 */
1400static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1401 v_VOID_t *pData)
1402{
1403 int status, i;
1404 tpSirWifiRadioStat pWifiRadioStat;
1405 tpSirWifiChannelStats pWifiChannelStats;
1406 struct sk_buff *vendor_event;
1407 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1408 struct nlattr *chList;
1409
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301410 ENTER();
1411
Sunil Duttc69bccb2014-05-26 21:30:20 +05301412 status = wlan_hdd_validate_context(pHddCtx);
1413 if (0 != status)
1414 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301415 return;
1416 }
1417 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1418
1419 hddLog(VOS_TRACE_LEVEL_INFO,
1420 "LL_STATS_RADIO"
1421 " radio is %d onTime is %u "
1422 " txTime is %u rxTime is %u "
1423 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301424 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301425 " onTimePnoScan is %u onTimeHs20 is %u "
1426 " numChannels is %u",
1427 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1428 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1429 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301430 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301431 pWifiRadioStat->onTimeRoamScan,
1432 pWifiRadioStat->onTimePnoScan,
1433 pWifiRadioStat->onTimeHs20,
1434 pWifiRadioStat->numChannels);
1435 /*
1436 * Allocate a size of 4096 for the Radio stats comprising
1437 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1438 * (tSirWifiChannelStats).Each channel data is put with an
1439 * NL attribute.The size of 4096 is considered assuming that
1440 * number of channels shall not exceed beyond 60 with the
1441 * sizeof (tSirWifiChannelStats) being 24 bytes.
1442 */
1443
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301444 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1445 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301446 if (!vendor_event)
1447 {
1448 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301449 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301450 return;
1451 }
1452
1453 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301454 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1455 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1456 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301457 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1458 pWifiRadioStat->radio) ||
1459 nla_put_u32(vendor_event,
1460 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1461 pWifiRadioStat->onTime) ||
1462 nla_put_u32(vendor_event,
1463 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1464 pWifiRadioStat->txTime) ||
1465 nla_put_u32(vendor_event,
1466 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1467 pWifiRadioStat->rxTime) ||
1468 nla_put_u32(vendor_event,
1469 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1470 pWifiRadioStat->onTimeScan) ||
1471 nla_put_u32(vendor_event,
1472 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1473 pWifiRadioStat->onTimeNbd) ||
1474 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301475 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1476 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301477 nla_put_u32(vendor_event,
1478 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1479 pWifiRadioStat->onTimeRoamScan) ||
1480 nla_put_u32(vendor_event,
1481 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1482 pWifiRadioStat->onTimePnoScan) ||
1483 nla_put_u32(vendor_event,
1484 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1485 pWifiRadioStat->onTimeHs20) ||
1486 nla_put_u32(vendor_event,
1487 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1488 pWifiRadioStat->numChannels))
1489 {
1490 hddLog(VOS_TRACE_LEVEL_ERROR,
1491 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1492 kfree_skb(vendor_event);
1493 return ;
1494 }
1495
1496 chList = nla_nest_start(vendor_event,
1497 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301498 if(!chList)
1499 {
1500 hddLog(VOS_TRACE_LEVEL_ERROR,
1501 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1502 __func__);
1503 kfree_skb(vendor_event);
1504 return;
1505 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301506 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1507 {
1508 struct nlattr *chInfo;
1509
1510 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1511 pWifiRadioStat->channels +
1512 (i * sizeof(tSirWifiChannelStats)));
1513
Sunil Duttc69bccb2014-05-26 21:30:20 +05301514 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301515 if(!chInfo)
1516 {
1517 hddLog(VOS_TRACE_LEVEL_ERROR,
1518 "%s: failed to put chInfo",
1519 __func__);
1520 kfree_skb(vendor_event);
1521 return;
1522 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301523
1524 if (nla_put_u32(vendor_event,
1525 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1526 pWifiChannelStats->channel.width) ||
1527 nla_put_u32(vendor_event,
1528 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1529 pWifiChannelStats->channel.centerFreq) ||
1530 nla_put_u32(vendor_event,
1531 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1532 pWifiChannelStats->channel.centerFreq0) ||
1533 nla_put_u32(vendor_event,
1534 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1535 pWifiChannelStats->channel.centerFreq1) ||
1536 nla_put_u32(vendor_event,
1537 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1538 pWifiChannelStats->onTime) ||
1539 nla_put_u32(vendor_event,
1540 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1541 pWifiChannelStats->ccaBusyTime))
1542 {
1543 hddLog(VOS_TRACE_LEVEL_ERROR,
1544 FL("cfg80211_vendor_event_alloc failed") );
1545 kfree_skb(vendor_event);
1546 return ;
1547 }
1548 nla_nest_end(vendor_event, chInfo);
1549 }
1550 nla_nest_end(vendor_event, chList);
1551
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301552 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301553
1554 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301555 return;
1556}
1557
1558/*
1559 * hdd_link_layer_stats_ind_callback () - This function is called after
1560 * receiving Link Layer indications from FW.This callback converts the firmware
1561 * data to the NL data and send the same to the kernel/upper layers.
1562 */
1563static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1564 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301565 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301566{
Dino Mycled3d50022014-07-07 12:58:25 +05301567 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1568 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301569 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301570 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301571 int status;
1572
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301573 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301574
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301575 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301576 if (0 != status)
1577 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301578 return;
1579 }
1580
Dino Mycled3d50022014-07-07 12:58:25 +05301581 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1582 if (NULL == pAdapter)
1583 {
1584 hddLog(VOS_TRACE_LEVEL_ERROR,
1585 FL(" MAC address %pM does not exist with host"),
1586 macAddr);
1587 return;
1588 }
1589
Sunil Duttc69bccb2014-05-26 21:30:20 +05301590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301591 "%s: Interface: %s LLStats indType: %d", __func__,
1592 pAdapter->dev->name, indType);
1593
Sunil Duttc69bccb2014-05-26 21:30:20 +05301594 switch (indType)
1595 {
1596 case SIR_HAL_LL_STATS_RESULTS_RSP:
1597 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301598 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301599 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1600 "respId = %u, moreResultToFollow = %u",
1601 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1602 macAddr, linkLayerStatsResults->respId,
1603 linkLayerStatsResults->moreResultToFollow);
1604
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301605 spin_lock(&hdd_context_lock);
1606 context = &pHddCtx->ll_stats_context;
1607 /* validate response received from target */
1608 if ((context->request_id != linkLayerStatsResults->respId) ||
1609 !(context->request_bitmap & linkLayerStatsResults->paramId))
1610 {
1611 spin_unlock(&hdd_context_lock);
1612 hddLog(LOGE,
1613 FL("Error : Request id %d response id %d request bitmap 0x%x"
1614 "response bitmap 0x%x"),
1615 context->request_id, linkLayerStatsResults->respId,
1616 context->request_bitmap, linkLayerStatsResults->paramId);
1617 return;
1618 }
1619 spin_unlock(&hdd_context_lock);
1620
Sunil Duttc69bccb2014-05-26 21:30:20 +05301621 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1622 {
1623 hdd_link_layer_process_radio_stats(pAdapter,
1624 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301625 spin_lock(&hdd_context_lock);
1626 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1627 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301628 }
1629 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1630 {
1631 hdd_link_layer_process_iface_stats(pAdapter,
1632 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301633 spin_lock(&hdd_context_lock);
1634 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1635 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301636 }
1637 else if ( linkLayerStatsResults->paramId &
1638 WMI_LINK_STATS_ALL_PEER )
1639 {
1640 hdd_link_layer_process_peer_stats(pAdapter,
1641 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301642 spin_lock(&hdd_context_lock);
1643 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1644 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301645 } /* WMI_LINK_STATS_ALL_PEER */
1646 else
1647 {
1648 hddLog(VOS_TRACE_LEVEL_ERROR,
1649 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1650 }
1651
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301652 spin_lock(&hdd_context_lock);
1653 /* complete response event if all requests are completed */
1654 if (0 == context->request_bitmap)
1655 complete(&context->response_event);
1656 spin_unlock(&hdd_context_lock);
1657
Sunil Duttc69bccb2014-05-26 21:30:20 +05301658 break;
1659 }
1660 default:
1661 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1662 break;
1663 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301664
1665 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301666 return;
1667}
1668
1669const struct
1670nla_policy
1671qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1672{
1673 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1674 { .type = NLA_U32 },
1675 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1676 { .type = NLA_U32 },
1677};
1678
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301679static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1680 struct wireless_dev *wdev,
1681 const void *data,
1682 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301683{
1684 int status;
1685 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301686 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301687 struct net_device *dev = wdev->netdev;
1688 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1689 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1690
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301691 ENTER();
1692
Sunil Duttc69bccb2014-05-26 21:30:20 +05301693 status = wlan_hdd_validate_context(pHddCtx);
1694 if (0 != status)
1695 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301696 return -EINVAL;
1697 }
1698
1699 if (NULL == pAdapter)
1700 {
1701 hddLog(VOS_TRACE_LEVEL_ERROR,
1702 FL("HDD adapter is Null"));
1703 return -ENODEV;
1704 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301705 /* check the LLStats Capability */
1706 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1707 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1708 {
1709 hddLog(VOS_TRACE_LEVEL_ERROR,
1710 FL("Link Layer Statistics not supported by Firmware"));
1711 return -EINVAL;
1712 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301713
1714 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1715 (struct nlattr *)data,
1716 data_len, qca_wlan_vendor_ll_set_policy))
1717 {
1718 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1719 return -EINVAL;
1720 }
1721 if (!tb_vendor
1722 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1723 {
1724 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1725 return -EINVAL;
1726 }
1727 if (!tb_vendor[
1728 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1729 {
1730 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1731 return -EINVAL;
1732 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301733 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301734 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301735
Dino Mycledf0a5d92014-07-04 09:41:55 +05301736 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301737 nla_get_u32(
1738 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1739
Dino Mycledf0a5d92014-07-04 09:41:55 +05301740 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301741 nla_get_u32(
1742 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1743
Dino Mycled3d50022014-07-07 12:58:25 +05301744 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1745 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301746
1747
1748 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301749 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1750 "Statistics Gathering = %d ",
1751 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1752 linkLayerStatsSetReq.mpduSizeThreshold,
1753 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301754
1755 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1756 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301757 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301758 {
1759 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1760 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301761 return -EINVAL;
1762
1763 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301764
Sunil Duttc69bccb2014-05-26 21:30:20 +05301765 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301766 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301767 {
1768 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1769 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301770 return -EINVAL;
1771 }
1772
1773 pAdapter->isLinkLayerStatsSet = 1;
1774
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301775 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301776 return 0;
1777}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301778static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1779 struct wireless_dev *wdev,
1780 const void *data,
1781 int data_len)
1782{
1783 int ret = 0;
1784
1785 vos_ssr_protect(__func__);
1786 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1787 vos_ssr_unprotect(__func__);
1788
1789 return ret;
1790}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301791
1792const struct
1793nla_policy
1794qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1795{
1796 /* Unsigned 32bit value provided by the caller issuing the GET stats
1797 * command. When reporting
1798 * the stats results, the driver uses the same value to indicate
1799 * which GET request the results
1800 * correspond to.
1801 */
1802 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1803
1804 /* Unsigned 32bit value . bit mask to identify what statistics are
1805 requested for retrieval */
1806 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1807};
1808
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301809static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1810 struct wireless_dev *wdev,
1811 const void *data,
1812 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301813{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301814 unsigned long rc;
1815 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301816 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1817 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301818 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301819 struct net_device *dev = wdev->netdev;
1820 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301821 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301822 int status;
1823
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301824 ENTER();
1825
Sunil Duttc69bccb2014-05-26 21:30:20 +05301826 status = wlan_hdd_validate_context(pHddCtx);
1827 if (0 != status)
1828 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301829 return -EINVAL ;
1830 }
1831
1832 if (NULL == pAdapter)
1833 {
1834 hddLog(VOS_TRACE_LEVEL_FATAL,
1835 "%s: HDD adapter is Null", __func__);
1836 return -ENODEV;
1837 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301838
1839 if (pHddStaCtx == NULL)
1840 {
1841 hddLog(VOS_TRACE_LEVEL_FATAL,
1842 "%s: HddStaCtx is Null", __func__);
1843 return -ENODEV;
1844 }
1845
Dino Mycledf0a5d92014-07-04 09:41:55 +05301846 /* check the LLStats Capability */
1847 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1848 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1849 {
1850 hddLog(VOS_TRACE_LEVEL_ERROR,
1851 FL("Link Layer Statistics not supported by Firmware"));
1852 return -EINVAL;
1853 }
1854
Sunil Duttc69bccb2014-05-26 21:30:20 +05301855
1856 if (!pAdapter->isLinkLayerStatsSet)
1857 {
1858 hddLog(VOS_TRACE_LEVEL_FATAL,
1859 "%s: isLinkLayerStatsSet : %d",
1860 __func__, pAdapter->isLinkLayerStatsSet);
1861 return -EINVAL;
1862 }
1863
Mukul Sharma10313ba2015-07-29 19:14:39 +05301864 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1865 {
1866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1867 "%s: Roaming in progress, so unable to proceed this request", __func__);
1868 return -EBUSY;
1869 }
1870
Sunil Duttc69bccb2014-05-26 21:30:20 +05301871 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1872 (struct nlattr *)data,
1873 data_len, qca_wlan_vendor_ll_get_policy))
1874 {
1875 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1876 return -EINVAL;
1877 }
1878
1879 if (!tb_vendor
1880 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1881 {
1882 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1883 return -EINVAL;
1884 }
1885
1886 if (!tb_vendor
1887 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1888 {
1889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1890 return -EINVAL;
1891 }
1892
Sunil Duttc69bccb2014-05-26 21:30:20 +05301893
Dino Mycledf0a5d92014-07-04 09:41:55 +05301894 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301895 nla_get_u32( tb_vendor[
1896 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301897 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301898 nla_get_u32( tb_vendor[
1899 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1900
Dino Mycled3d50022014-07-07 12:58:25 +05301901 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1902 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301903
1904 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301905 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1906 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301907 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301908
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301909 spin_lock(&hdd_context_lock);
1910 context = &pHddCtx->ll_stats_context;
1911 context->request_id = linkLayerStatsGetReq.reqId;
1912 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1913 INIT_COMPLETION(context->response_event);
1914 spin_unlock(&hdd_context_lock);
1915
Sunil Duttc69bccb2014-05-26 21:30:20 +05301916 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301917 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301918 {
1919 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1920 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301921 return -EINVAL;
1922 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301923
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301924 rc = wait_for_completion_timeout(&context->response_event,
1925 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1926 if (!rc)
1927 {
1928 hddLog(LOGE,
1929 FL("Target response timed out request id %d request bitmap 0x%x"),
1930 context->request_id, context->request_bitmap);
1931 return -ETIMEDOUT;
1932 }
1933
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301934 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301935 return 0;
1936}
1937
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301938static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1939 struct wireless_dev *wdev,
1940 const void *data,
1941 int data_len)
1942{
1943 int ret = 0;
1944
1945 vos_ssr_protect(__func__);
1946 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1947 vos_ssr_unprotect(__func__);
1948
1949 return ret;
1950}
1951
Sunil Duttc69bccb2014-05-26 21:30:20 +05301952const struct
1953nla_policy
1954qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1955{
1956 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1957 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1958 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1959 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1960};
1961
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301962static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1963 struct wireless_dev *wdev,
1964 const void *data,
1965 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301966{
1967 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1968 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301969 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301970 struct net_device *dev = wdev->netdev;
1971 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1972 u32 statsClearReqMask;
1973 u8 stopReq;
1974 int status;
1975
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301976 ENTER();
1977
Sunil Duttc69bccb2014-05-26 21:30:20 +05301978 status = wlan_hdd_validate_context(pHddCtx);
1979 if (0 != status)
1980 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301981 return -EINVAL;
1982 }
1983
1984 if (NULL == pAdapter)
1985 {
1986 hddLog(VOS_TRACE_LEVEL_FATAL,
1987 "%s: HDD adapter is Null", __func__);
1988 return -ENODEV;
1989 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301990 /* check the LLStats Capability */
1991 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1992 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1993 {
1994 hddLog(VOS_TRACE_LEVEL_ERROR,
1995 FL("Enable LLStats Capability"));
1996 return -EINVAL;
1997 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301998
1999 if (!pAdapter->isLinkLayerStatsSet)
2000 {
2001 hddLog(VOS_TRACE_LEVEL_FATAL,
2002 "%s: isLinkLayerStatsSet : %d",
2003 __func__, pAdapter->isLinkLayerStatsSet);
2004 return -EINVAL;
2005 }
2006
2007 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2008 (struct nlattr *)data,
2009 data_len, qca_wlan_vendor_ll_clr_policy))
2010 {
2011 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2012 return -EINVAL;
2013 }
2014
2015 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2016
2017 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2018 {
2019 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2020 return -EINVAL;
2021
2022 }
2023
Sunil Duttc69bccb2014-05-26 21:30:20 +05302024
Dino Mycledf0a5d92014-07-04 09:41:55 +05302025 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302026 nla_get_u32(
2027 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2028
Dino Mycledf0a5d92014-07-04 09:41:55 +05302029 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302030 nla_get_u8(
2031 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2032
2033 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302034 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302035
Dino Mycled3d50022014-07-07 12:58:25 +05302036 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2037 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302038
2039 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302040 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2041 "statsClearReqMask = 0x%X, stopReq = %d",
2042 linkLayerStatsClearReq.reqId,
2043 linkLayerStatsClearReq.macAddr,
2044 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302045 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302046
2047 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302048 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302049 {
2050 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302051 hdd_station_ctx_t *pHddStaCtx;
2052
2053 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2054 if (VOS_STATUS_SUCCESS !=
2055 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2056 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2057 {
2058 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2059 "WLANTL_ClearInterfaceStats Failed", __func__);
2060 return -EINVAL;
2061 }
2062 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2063 (statsClearReqMask & WIFI_STATS_IFACE)) {
2064 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2065 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2066 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2067 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2068 }
2069
Sunil Duttc69bccb2014-05-26 21:30:20 +05302070 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2071 2 * sizeof(u32) +
2072 NLMSG_HDRLEN);
2073
2074 if (temp_skbuff != NULL)
2075 {
2076
2077 if (nla_put_u32(temp_skbuff,
2078 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2079 statsClearReqMask) ||
2080 nla_put_u32(temp_skbuff,
2081 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2082 stopReq))
2083 {
2084 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2085 kfree_skb(temp_skbuff);
2086 return -EINVAL;
2087 }
2088 /* If the ask is to stop the stats collection as part of clear
2089 * (stopReq = 1) , ensure that no further requests of get
2090 * go to the firmware by having isLinkLayerStatsSet set to 0.
2091 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302092 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302093 * case the firmware is just asked to clear the statistics.
2094 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302095 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302096 pAdapter->isLinkLayerStatsSet = 0;
2097 return cfg80211_vendor_cmd_reply(temp_skbuff);
2098 }
2099 return -ENOMEM;
2100 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302101
2102 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302103 return -EINVAL;
2104}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302105static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2106 struct wireless_dev *wdev,
2107 const void *data,
2108 int data_len)
2109{
2110 int ret = 0;
2111
2112 vos_ssr_protect(__func__);
2113 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2114 vos_ssr_unprotect(__func__);
2115
2116 return ret;
2117
2118
2119}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302120#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2121
Dino Mycle6fb96c12014-06-10 11:52:40 +05302122#ifdef WLAN_FEATURE_EXTSCAN
2123static const struct nla_policy
2124wlan_hdd_extscan_config_policy
2125 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2126{
2127 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2128 { .type = NLA_U32 },
2129 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2130 { .type = NLA_U32 },
2131 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2132 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2133 { .type = NLA_U32 },
2134 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2135 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2136
2137 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2138 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2139 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2140 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2141 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302142 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2143 { .type = NLA_U32 },
2144 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2145 { .type = NLA_U32 },
2146 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2147 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302148 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2149 { .type = NLA_U32 },
2150 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2151 { .type = NLA_U32 },
2152 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2153 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302154 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2155 { .type = NLA_U8 },
2156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302157 { .type = NLA_U8 },
2158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2159 { .type = NLA_U8 },
2160 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2161 { .type = NLA_U8 },
2162
2163 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2164 { .type = NLA_U32 },
2165 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2166 { .type = NLA_UNSPEC },
2167 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2168 { .type = NLA_S32 },
2169 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2170 { .type = NLA_S32 },
2171 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2172 { .type = NLA_U32 },
2173 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2174 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302175 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2176 { .type = NLA_U32 },
2177 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2178 { .type = NLA_BINARY,
2179 .len = IEEE80211_MAX_SSID_LEN + 1 },
2180 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302181 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302182 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2183 { .type = NLA_U32 },
2184 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2185 { .type = NLA_U8 },
2186 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2187 { .type = NLA_S32 },
2188 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2189 { .type = NLA_S32 },
2190 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2191 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302192};
2193
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302194/**
2195 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2196 * @ctx: hdd global context
2197 * @data: capabilities data
2198 *
2199 * Return: none
2200 */
2201static void
2202wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302203{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302204 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302205 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302206 tSirEXTScanCapabilitiesEvent *data =
2207 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302208
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302209 ENTER();
2210
2211 if (wlan_hdd_validate_context(pHddCtx))
2212 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302213 return;
2214 }
2215
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302216 if (!pMsg)
2217 {
2218 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2219 return;
2220 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302221
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302222 vos_spin_lock_acquire(&hdd_context_lock);
2223
2224 context = &pHddCtx->ext_scan_context;
2225 /* validate response received from target*/
2226 if (context->request_id != data->requestId)
2227 {
2228 vos_spin_lock_release(&hdd_context_lock);
2229 hddLog(LOGE,
2230 FL("Target response id did not match: request_id %d resposne_id %d"),
2231 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302232 return;
2233 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302234 else
2235 {
2236 context->capability_response = *data;
2237 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302238 }
2239
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302240 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302241
Dino Mycle6fb96c12014-06-10 11:52:40 +05302242 return;
2243}
2244
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302245/*
2246 * define short names for the global vendor params
2247 * used by wlan_hdd_send_ext_scan_capability()
2248 */
2249#define PARAM_REQUEST_ID \
2250 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2251#define PARAM_STATUS \
2252 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2253#define MAX_SCAN_CACHE_SIZE \
2254 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2255#define MAX_SCAN_BUCKETS \
2256 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2257#define MAX_AP_CACHE_PER_SCAN \
2258 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2259#define MAX_RSSI_SAMPLE_SIZE \
2260 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2261#define MAX_SCAN_RPT_THRHOLD \
2262 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2263#define MAX_HOTLIST_BSSIDS \
2264 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2265#define MAX_BSSID_HISTORY_ENTRIES \
2266 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2267#define MAX_HOTLIST_SSIDS \
2268 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302269#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2270 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302271
2272static int wlan_hdd_send_ext_scan_capability(void *ctx)
2273{
2274 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2275 struct sk_buff *skb = NULL;
2276 int ret;
2277 tSirEXTScanCapabilitiesEvent *data;
2278 tANI_U32 nl_buf_len;
2279
2280 ret = wlan_hdd_validate_context(pHddCtx);
2281 if (0 != ret)
2282 {
2283 return ret;
2284 }
2285
2286 data = &(pHddCtx->ext_scan_context.capability_response);
2287
2288 nl_buf_len = NLMSG_HDRLEN;
2289 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2290 (sizeof(data->status) + NLA_HDRLEN) +
2291 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2292 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2293 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2294 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2295 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2296 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2297 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2298 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2299
2300 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2301
2302 if (!skb)
2303 {
2304 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2305 return -ENOMEM;
2306 }
2307
2308 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2309 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2310 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2311 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2312 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2313 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2314 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2315 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2316
2317 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2318 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2319 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2320 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2321 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2322 data->maxApPerScan) ||
2323 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2324 data->maxRssiSampleSize) ||
2325 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2326 data->maxScanReportingThreshold) ||
2327 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2328 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2329 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302330 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2331 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302332 {
2333 hddLog(LOGE, FL("nla put fail"));
2334 goto nla_put_failure;
2335 }
2336
2337 cfg80211_vendor_cmd_reply(skb);
2338 return 0;
2339
2340nla_put_failure:
2341 kfree_skb(skb);
2342 return -EINVAL;;
2343}
2344
2345/*
2346 * done with short names for the global vendor params
2347 * used by wlan_hdd_send_ext_scan_capability()
2348 */
2349#undef PARAM_REQUEST_ID
2350#undef PARAM_STATUS
2351#undef MAX_SCAN_CACHE_SIZE
2352#undef MAX_SCAN_BUCKETS
2353#undef MAX_AP_CACHE_PER_SCAN
2354#undef MAX_RSSI_SAMPLE_SIZE
2355#undef MAX_SCAN_RPT_THRHOLD
2356#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302357#undef MAX_BSSID_HISTORY_ENTRIES
2358#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302359
2360static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2361{
2362 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2363 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302364 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302365 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302366
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302367 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302368
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302369 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302370 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302371
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302372 if (!pMsg)
2373 {
2374 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302375 return;
2376 }
2377
Dino Mycle6fb96c12014-06-10 11:52:40 +05302378 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2379 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2380
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302381 context = &pHddCtx->ext_scan_context;
2382 spin_lock(&hdd_context_lock);
2383 if (context->request_id == pData->requestId) {
2384 context->response_status = pData->status ? -EINVAL : 0;
2385 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302386 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302387 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302388
2389 /*
2390 * Store the Request ID for comparing with the requestID obtained
2391 * in other requests.HDD shall return a failure is the extscan_stop
2392 * request is issued with a different requestId as that of the
2393 * extscan_start request. Also, This requestId shall be used while
2394 * indicating the full scan results to the upper layers.
2395 * The requestId is stored with the assumption that the firmware
2396 * shall return the ext scan start request's requestId in ext scan
2397 * start response.
2398 */
2399 if (pData->status == 0)
2400 pMac->sme.extScanStartReqId = pData->requestId;
2401
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302402 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302403 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302404}
2405
2406
2407static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2408{
2409 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2410 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302411 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302412
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302413 ENTER();
2414
2415 if (wlan_hdd_validate_context(pHddCtx)){
2416 return;
2417 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302418
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302419 if (!pMsg)
2420 {
2421 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302422 return;
2423 }
2424
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302425 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2426 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302427
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302428 context = &pHddCtx->ext_scan_context;
2429 spin_lock(&hdd_context_lock);
2430 if (context->request_id == pData->requestId) {
2431 context->response_status = pData->status ? -EINVAL : 0;
2432 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302433 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302434 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302435
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302436 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302437 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302438}
2439
Dino Mycle6fb96c12014-06-10 11:52:40 +05302440static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2441 void *pMsg)
2442{
2443 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302444 tpSirEXTScanSetBssidHotListRspParams pData =
2445 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302446 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302447
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302448 ENTER();
2449
2450 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302451 return;
2452 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302453
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302454 if (!pMsg)
2455 {
2456 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2457 return;
2458 }
2459
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302460 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2461 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302462
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302463 context = &pHddCtx->ext_scan_context;
2464 spin_lock(&hdd_context_lock);
2465 if (context->request_id == pData->requestId) {
2466 context->response_status = pData->status ? -EINVAL : 0;
2467 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302468 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302469 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302470
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302471 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302472 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302473}
2474
2475static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2476 void *pMsg)
2477{
2478 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302479 tpSirEXTScanResetBssidHotlistRspParams pData =
2480 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302481 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302482
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302483 ENTER();
2484
2485 if (wlan_hdd_validate_context(pHddCtx)) {
2486 return;
2487 }
2488 if (!pMsg)
2489 {
2490 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302491 return;
2492 }
2493
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302494 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2495 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302496
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302497 context = &pHddCtx->ext_scan_context;
2498 spin_lock(&hdd_context_lock);
2499 if (context->request_id == pData->requestId) {
2500 context->response_status = pData->status ? -EINVAL : 0;
2501 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302502 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302503 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302504
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302505 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302506 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302507}
2508
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302509static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2510 void *pMsg)
2511{
2512 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2513 tpSirEXTScanSetSsidHotListRspParams pData =
2514 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2515 struct hdd_ext_scan_context *context;
2516
2517 if (wlan_hdd_validate_context(pHddCtx)){
2518 return;
2519 }
2520
2521 if (!pMsg)
2522 {
2523 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2524 return;
2525 }
2526
2527 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2528 pData->status);
2529
2530 context = &pHddCtx->ext_scan_context;
2531 spin_lock(&hdd_context_lock);
2532 if (context->request_id == pData->requestId) {
2533 context->response_status = pData->status ? -EINVAL : 0;
2534 complete(&context->response_event);
2535 }
2536 spin_unlock(&hdd_context_lock);
2537
2538 return;
2539}
2540
2541static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2542 void *pMsg)
2543{
2544 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2545 tpSirEXTScanResetSsidHotlistRspParams pData =
2546 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2547 struct hdd_ext_scan_context *context;
2548
2549 if (wlan_hdd_validate_context(pHddCtx)) {
2550 return;
2551 }
2552 if (!pMsg)
2553 {
2554 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2555 return;
2556 }
2557
2558 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2559 pData->status);
2560
2561 context = &pHddCtx->ext_scan_context;
2562 spin_lock(&hdd_context_lock);
2563 if (context->request_id == pData->requestId) {
2564 context->response_status = pData->status ? -EINVAL : 0;
2565 complete(&context->response_event);
2566 }
2567 spin_unlock(&hdd_context_lock);
2568
2569 return;
2570}
2571
2572
Dino Mycle6fb96c12014-06-10 11:52:40 +05302573static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2574 void *pMsg)
2575{
2576 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2577 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302578 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302579 tANI_S32 totalResults;
2580 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302581 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2582 struct hdd_ext_scan_context *context;
2583 bool ignore_cached_results = false;
2584 tExtscanCachedScanResult *result;
2585 struct nlattr *nla_results;
2586 tANI_U16 ieLength= 0;
2587 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302588
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302589 ENTER();
2590
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302591 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302592 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302593
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302594 if (!pMsg)
2595 {
2596 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2597 return;
2598 }
2599
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302600 spin_lock(&hdd_context_lock);
2601 context = &pHddCtx->ext_scan_context;
2602 ignore_cached_results = context->ignore_cached_results;
2603 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302604
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302605 if (ignore_cached_results) {
2606 hddLog(LOGE,
2607 FL("Ignore the cached results received after timeout"));
2608 return;
2609 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302610
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302611 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2612 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302613
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302614 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302615
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302616 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2617 scan_id_index++) {
2618 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302619
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302620 totalResults = result->num_results;
2621 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2622 result->scan_id, result->flags, totalResults);
2623 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302624
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302625 do{
2626 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2627 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2628 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302629
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302630 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2631 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2632
2633 if (!skb) {
2634 hddLog(VOS_TRACE_LEVEL_ERROR,
2635 FL("cfg80211_vendor_event_alloc failed"));
2636 return;
2637 }
2638
2639 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2640
2641 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2642 pData->requestId) ||
2643 nla_put_u32(skb,
2644 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2645 resultsPerEvent)) {
2646 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2647 goto fail;
2648 }
2649 if (nla_put_u8(skb,
2650 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2651 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302652 {
2653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2654 goto fail;
2655 }
2656
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302657 if (nla_put_u32(skb,
2658 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2659 result->scan_id)) {
2660 hddLog(LOGE, FL("put fail"));
2661 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302662 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302663
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302664 nla_results = nla_nest_start(skb,
2665 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2666 if (!nla_results)
2667 goto fail;
2668
2669 if (resultsPerEvent) {
2670 struct nlattr *aps;
2671 struct nlattr *nla_result;
2672
2673 nla_result = nla_nest_start(skb, scan_id_index);
2674 if(!nla_result)
2675 goto fail;
2676
2677 if (nla_put_u32(skb,
2678 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2679 result->scan_id) ||
2680 nla_put_u32(skb,
2681 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2682 result->flags) ||
2683 nla_put_u32(skb,
2684 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2685 totalResults)) {
2686 hddLog(LOGE, FL("put fail"));
2687 goto fail;
2688 }
2689
2690 aps = nla_nest_start(skb,
2691 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2692 if (!aps)
2693 {
2694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2695 goto fail;
2696 }
2697
2698 head_ptr = (tpSirWifiScanResult) &(result->ap);
2699
2700 for (j = 0; j < resultsPerEvent; j++, i++) {
2701 struct nlattr *ap;
2702 pSirWifiScanResult = head_ptr + i;
2703
2704 /*
2705 * Firmware returns timestamp from WiFi turn ON till
2706 * BSSID was cached (in seconds). Add this with
2707 * time gap between system boot up to WiFi turn ON
2708 * to derive the time since boot when the
2709 * BSSID was cached.
2710 */
2711 pSirWifiScanResult->ts += pHddCtx->wifi_turn_on_time_since_boot;
2712 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2713 "Ssid (%s)"
2714 "Bssid: %pM "
2715 "Channel (%u)"
2716 "Rssi (%d)"
2717 "RTT (%u)"
2718 "RTT_SD (%u)"
2719 "Beacon Period %u"
2720 "Capability 0x%x "
2721 "Ie length %d",
2722 i,
2723 pSirWifiScanResult->ts,
2724 pSirWifiScanResult->ssid,
2725 pSirWifiScanResult->bssid,
2726 pSirWifiScanResult->channel,
2727 pSirWifiScanResult->rssi,
2728 pSirWifiScanResult->rtt,
2729 pSirWifiScanResult->rtt_sd,
2730 pSirWifiScanResult->beaconPeriod,
2731 pSirWifiScanResult->capability,
2732 ieLength);
2733
2734 ap = nla_nest_start(skb, j + 1);
2735 if (!ap)
2736 {
2737 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2738 goto fail;
2739 }
2740
2741 if (nla_put_u64(skb,
2742 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2743 pSirWifiScanResult->ts) )
2744 {
2745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2746 goto fail;
2747 }
2748 if (nla_put(skb,
2749 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2750 sizeof(pSirWifiScanResult->ssid),
2751 pSirWifiScanResult->ssid) )
2752 {
2753 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2754 goto fail;
2755 }
2756 if (nla_put(skb,
2757 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2758 sizeof(pSirWifiScanResult->bssid),
2759 pSirWifiScanResult->bssid) )
2760 {
2761 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2762 goto fail;
2763 }
2764 if (nla_put_u32(skb,
2765 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2766 pSirWifiScanResult->channel) )
2767 {
2768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2769 goto fail;
2770 }
2771 if (nla_put_s32(skb,
2772 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2773 pSirWifiScanResult->rssi) )
2774 {
2775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2776 goto fail;
2777 }
2778 if (nla_put_u32(skb,
2779 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2780 pSirWifiScanResult->rtt) )
2781 {
2782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2783 goto fail;
2784 }
2785 if (nla_put_u32(skb,
2786 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2787 pSirWifiScanResult->rtt_sd))
2788 {
2789 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2790 goto fail;
2791 }
2792 if (nla_put_u32(skb,
2793 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2794 pSirWifiScanResult->beaconPeriod))
2795 {
2796 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2797 goto fail;
2798 }
2799 if (nla_put_u32(skb,
2800 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2801 pSirWifiScanResult->capability))
2802 {
2803 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2804 goto fail;
2805 }
2806 if (nla_put_u32(skb,
2807 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2808 ieLength))
2809 {
2810 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2811 goto fail;
2812 }
2813
2814 if (ieLength)
2815 if (nla_put(skb,
2816 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2817 ieLength, ie)) {
2818 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2819 goto fail;
2820 }
2821
2822 nla_nest_end(skb, ap);
2823 }
2824 nla_nest_end(skb, aps);
2825 nla_nest_end(skb, nla_result);
2826 }
2827
2828 nla_nest_end(skb, nla_results);
2829
2830 cfg80211_vendor_cmd_reply(skb);
2831
2832 } while (totalResults > 0);
2833 }
2834
2835 if (!pData->moreData) {
2836 spin_lock(&hdd_context_lock);
2837 context->response_status = 0;
2838 complete(&context->response_event);
2839 spin_unlock(&hdd_context_lock);
2840 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302841
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302842 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302843 return;
2844fail:
2845 kfree_skb(skb);
2846 return;
2847}
2848
2849static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2850 void *pMsg)
2851{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302852 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302853 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2854 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302855 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302856
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302857 ENTER();
2858
2859 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302860 hddLog(LOGE,
2861 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302862 return;
2863 }
2864 if (!pMsg)
2865 {
2866 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302867 return;
2868 }
2869
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302870 if (pData->bss_found)
2871 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2872 else
2873 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2874
Dino Mycle6fb96c12014-06-10 11:52:40 +05302875 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302876#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2877 NULL,
2878#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302879 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302880 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302881
2882 if (!skb) {
2883 hddLog(VOS_TRACE_LEVEL_ERROR,
2884 FL("cfg80211_vendor_event_alloc failed"));
2885 return;
2886 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302887
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302888 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2889 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2890 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2891 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2892
2893 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302894 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2895 "Ssid (%s) "
2896 "Bssid (" MAC_ADDRESS_STR ") "
2897 "Channel (%u) "
2898 "Rssi (%d) "
2899 "RTT (%u) "
2900 "RTT_SD (%u) ",
2901 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302902 pData->bssHotlist[i].ts,
2903 pData->bssHotlist[i].ssid,
2904 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2905 pData->bssHotlist[i].channel,
2906 pData->bssHotlist[i].rssi,
2907 pData->bssHotlist[i].rtt,
2908 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302909 }
2910
2911 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2912 pData->requestId) ||
2913 nla_put_u32(skb,
2914 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302915 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302916 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2917 goto fail;
2918 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302919 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302920 struct nlattr *aps;
2921
2922 aps = nla_nest_start(skb,
2923 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2924 if (!aps)
2925 goto fail;
2926
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302927 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302928 struct nlattr *ap;
2929
2930 ap = nla_nest_start(skb, i + 1);
2931 if (!ap)
2932 goto fail;
2933
2934 if (nla_put_u64(skb,
2935 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302936 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302937 nla_put(skb,
2938 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302939 sizeof(pData->bssHotlist[i].ssid),
2940 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302941 nla_put(skb,
2942 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302943 sizeof(pData->bssHotlist[i].bssid),
2944 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302945 nla_put_u32(skb,
2946 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302947 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302948 nla_put_s32(skb,
2949 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302950 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302951 nla_put_u32(skb,
2952 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302953 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302954 nla_put_u32(skb,
2955 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302956 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302957 goto fail;
2958
2959 nla_nest_end(skb, ap);
2960 }
2961 nla_nest_end(skb, aps);
2962
2963 if (nla_put_u8(skb,
2964 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2965 pData->moreData))
2966 goto fail;
2967 }
2968
2969 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302970 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302971 return;
2972
2973fail:
2974 kfree_skb(skb);
2975 return;
2976
2977}
Dino Mycle6fb96c12014-06-10 11:52:40 +05302978
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302979/**
2980 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
2981 * Handle an SSID hotlist match event
2982 * @ctx: HDD context registered with SME
2983 * @event: The SSID hotlist match event
2984 *
2985 * This function will take an SSID match event that was generated by
2986 * firmware and will convert it into a cfg80211 vendor event which is
2987 * sent to userspace.
2988 *
2989 * Return: none
2990 */
2991static void
2992wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
2993 void *pMsg)
2994{
2995 hdd_context_t *hdd_ctx = ctx;
2996 struct sk_buff *skb;
2997 tANI_U32 i, index;
2998 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
2999
3000 ENTER();
3001
3002 if (wlan_hdd_validate_context(hdd_ctx)) {
3003 hddLog(LOGE,
3004 FL("HDD context is not valid or response"));
3005 return;
3006 }
3007 if (!pMsg)
3008 {
3009 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3010 return;
3011 }
3012
3013 if (pData->ssid_found) {
3014 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3015 hddLog(LOG1, "SSID hotlist found");
3016 } else {
3017 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3018 hddLog(LOG1, "SSID hotlist lost");
3019 }
3020
3021 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3022#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3023 NULL,
3024#endif
3025 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3026 index, GFP_KERNEL);
3027
3028 if (!skb) {
3029 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3030 return;
3031 }
3032 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3033 pData->requestId, pData->numHotlistSsid, pData->moreData);
3034
3035 for (i = 0; i < pData->numHotlistSsid; i++) {
3036 hddLog(LOG1, "[i=%d] Timestamp %llu "
3037 "Ssid: %s "
3038 "Bssid (" MAC_ADDRESS_STR ") "
3039 "Channel %u "
3040 "Rssi %d "
3041 "RTT %u "
3042 "RTT_SD %u",
3043 i,
3044 pData->ssidHotlist[i].ts,
3045 pData->ssidHotlist[i].ssid,
3046 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3047 pData->ssidHotlist[i].channel,
3048 pData->ssidHotlist[i].rssi,
3049 pData->ssidHotlist[i].rtt,
3050 pData->ssidHotlist[i].rtt_sd);
3051 }
3052
3053 if (nla_put_u32(skb,
3054 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3055 pData->requestId) ||
3056 nla_put_u32(skb,
3057 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3058 pData->numHotlistSsid)) {
3059 hddLog(LOGE, FL("put fail"));
3060 goto fail;
3061 }
3062
3063 if (pData->numHotlistSsid) {
3064 struct nlattr *aps;
3065 aps = nla_nest_start(skb,
3066 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3067 if (!aps) {
3068 hddLog(LOGE, FL("nest fail"));
3069 goto fail;
3070 }
3071
3072 for (i = 0; i < pData->numHotlistSsid; i++) {
3073 struct nlattr *ap;
3074
3075 ap = nla_nest_start(skb, i);
3076 if (!ap) {
3077 hddLog(LOGE, FL("nest fail"));
3078 goto fail;
3079 }
3080
3081 if (nla_put_u64(skb,
3082 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3083 pData->ssidHotlist[i].ts) ||
3084 nla_put(skb,
3085 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3086 sizeof(pData->ssidHotlist[i].ssid),
3087 pData->ssidHotlist[i].ssid) ||
3088 nla_put(skb,
3089 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3090 sizeof(pData->ssidHotlist[i].bssid),
3091 pData->ssidHotlist[i].bssid) ||
3092 nla_put_u32(skb,
3093 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3094 pData->ssidHotlist[i].channel) ||
3095 nla_put_s32(skb,
3096 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3097 pData->ssidHotlist[i].rssi) ||
3098 nla_put_u32(skb,
3099 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3100 pData->ssidHotlist[i].rtt) ||
3101 nla_put_u32(skb,
3102 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3103 pData->ssidHotlist[i].rtt_sd)) {
3104 hddLog(LOGE, FL("put fail"));
3105 goto fail;
3106 }
3107 nla_nest_end(skb, ap);
3108 }
3109 nla_nest_end(skb, aps);
3110
3111 if (nla_put_u8(skb,
3112 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3113 pData->moreData)) {
3114 hddLog(LOGE, FL("put fail"));
3115 goto fail;
3116 }
3117 }
3118
3119 cfg80211_vendor_event(skb, GFP_KERNEL);
3120 return;
3121
3122fail:
3123 kfree_skb(skb);
3124 return;
3125
3126}
3127
3128
Dino Mycle6fb96c12014-06-10 11:52:40 +05303129static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3130 void *pMsg)
3131{
3132 struct sk_buff *skb;
3133 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3134 tpSirWifiFullScanResultEvent pData =
3135 (tpSirWifiFullScanResultEvent) (pMsg);
3136
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303137 ENTER();
3138
3139 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303140 hddLog(LOGE,
3141 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303142 return;
3143 }
3144 if (!pMsg)
3145 {
3146 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303147 return;
3148 }
3149
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303150 /*
3151 * If the full scan result including IE data exceeds NL 4K size
3152 * limitation, drop that beacon/probe rsp frame.
3153 */
3154 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3155 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3156 return;
3157 }
3158
Dino Mycle6fb96c12014-06-10 11:52:40 +05303159 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303160#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3161 NULL,
3162#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303163 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3164 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3165 GFP_KERNEL);
3166
3167 if (!skb) {
3168 hddLog(VOS_TRACE_LEVEL_ERROR,
3169 FL("cfg80211_vendor_event_alloc failed"));
3170 return;
3171 }
3172
Dino Mycle6fb96c12014-06-10 11:52:40 +05303173 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3174 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3175 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3176 "Ssid (%s)"
3177 "Bssid (" MAC_ADDRESS_STR ")"
3178 "Channel (%u)"
3179 "Rssi (%d)"
3180 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303181 "RTT_SD (%u)"
3182 "Bcn Period %d"
3183 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303184 pData->ap.ts,
3185 pData->ap.ssid,
3186 MAC_ADDR_ARRAY(pData->ap.bssid),
3187 pData->ap.channel,
3188 pData->ap.rssi,
3189 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303190 pData->ap.rtt_sd,
3191 pData->ap.beaconPeriod,
3192 pData->ap.capability);
3193
Dino Mycle6fb96c12014-06-10 11:52:40 +05303194 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3195 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3196 pData->requestId) ||
3197 nla_put_u64(skb,
3198 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3199 pData->ap.ts) ||
3200 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3201 sizeof(pData->ap.ssid),
3202 pData->ap.ssid) ||
3203 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3204 WNI_CFG_BSSID_LEN,
3205 pData->ap.bssid) ||
3206 nla_put_u32(skb,
3207 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3208 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303209 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303210 pData->ap.rssi) ||
3211 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3212 pData->ap.rtt) ||
3213 nla_put_u32(skb,
3214 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3215 pData->ap.rtt_sd) ||
3216 nla_put_u16(skb,
3217 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3218 pData->ap.beaconPeriod) ||
3219 nla_put_u16(skb,
3220 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3221 pData->ap.capability) ||
3222 nla_put_u32(skb,
3223 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303224 pData->ieLength) ||
3225 nla_put_u8(skb,
3226 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3227 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303228 {
3229 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3230 goto nla_put_failure;
3231 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303232
3233 if (pData->ieLength) {
3234 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3235 pData->ieLength,
3236 pData->ie))
3237 {
3238 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3239 goto nla_put_failure;
3240 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303241 }
3242
3243 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303244 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303245 return;
3246
3247nla_put_failure:
3248 kfree_skb(skb);
3249 return;
3250}
3251
3252static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3253 void *pMsg)
3254{
3255 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3256 struct sk_buff *skb = NULL;
3257 tpSirEXTScanResultsAvailableIndParams pData =
3258 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3259
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303260 ENTER();
3261
3262 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303263 hddLog(LOGE,
3264 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303265 return;
3266 }
3267 if (!pMsg)
3268 {
3269 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303270 return;
3271 }
3272
3273 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303274#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3275 NULL,
3276#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303277 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3278 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3279 GFP_KERNEL);
3280
3281 if (!skb) {
3282 hddLog(VOS_TRACE_LEVEL_ERROR,
3283 FL("cfg80211_vendor_event_alloc failed"));
3284 return;
3285 }
3286
Dino Mycle6fb96c12014-06-10 11:52:40 +05303287 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3288 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3289 pData->numResultsAvailable);
3290 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3291 pData->requestId) ||
3292 nla_put_u32(skb,
3293 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3294 pData->numResultsAvailable)) {
3295 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3296 goto nla_put_failure;
3297 }
3298
3299 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303300 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303301 return;
3302
3303nla_put_failure:
3304 kfree_skb(skb);
3305 return;
3306}
3307
3308static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3309{
3310 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3311 struct sk_buff *skb = NULL;
3312 tpSirEXTScanProgressIndParams pData =
3313 (tpSirEXTScanProgressIndParams) pMsg;
3314
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303315 ENTER();
3316
3317 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303318 hddLog(LOGE,
3319 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303320 return;
3321 }
3322 if (!pMsg)
3323 {
3324 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303325 return;
3326 }
3327
3328 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303329#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3330 NULL,
3331#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303332 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3333 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3334 GFP_KERNEL);
3335
3336 if (!skb) {
3337 hddLog(VOS_TRACE_LEVEL_ERROR,
3338 FL("cfg80211_vendor_event_alloc failed"));
3339 return;
3340 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303341 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303342 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3343 pData->extScanEventType);
3344 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3345 pData->status);
3346
3347 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3348 pData->extScanEventType) ||
3349 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303350 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3351 pData->requestId) ||
3352 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303353 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3354 pData->status)) {
3355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3356 goto nla_put_failure;
3357 }
3358
3359 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303360 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303361 return;
3362
3363nla_put_failure:
3364 kfree_skb(skb);
3365 return;
3366}
3367
3368void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3369 void *pMsg)
3370{
3371 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3372
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303373 ENTER();
3374
Dino Mycle6fb96c12014-06-10 11:52:40 +05303375 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303376 return;
3377 }
3378
3379 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3380
3381
3382 switch(evType) {
3383 case SIR_HAL_EXTSCAN_START_RSP:
3384 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3385 break;
3386
3387 case SIR_HAL_EXTSCAN_STOP_RSP:
3388 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3389 break;
3390 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3391 /* There is no need to send this response to upper layer
3392 Just log the message */
3393 hddLog(VOS_TRACE_LEVEL_INFO,
3394 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3395 break;
3396 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3397 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3398 break;
3399
3400 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3401 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3402 break;
3403
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303404 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3405 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3406 break;
3407
3408 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3409 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3410 break;
3411
Dino Mycle6fb96c12014-06-10 11:52:40 +05303412 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303413 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303414 break;
3415 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3416 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3417 break;
3418 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3419 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3420 break;
3421 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3422 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3423 break;
3424 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3425 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3426 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303427 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3428 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3429 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303430 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3431 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3432 break;
3433 default:
3434 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3435 break;
3436 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303437 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303438}
3439
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303440static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3441 struct wireless_dev *wdev,
3442 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303443{
Dino Myclee8843b32014-07-04 14:21:45 +05303444 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303445 struct net_device *dev = wdev->netdev;
3446 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3447 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3448 struct nlattr
3449 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3450 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303451 struct hdd_ext_scan_context *context;
3452 unsigned long rc;
3453 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303454
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303455 ENTER();
3456
Dino Mycle6fb96c12014-06-10 11:52:40 +05303457 status = wlan_hdd_validate_context(pHddCtx);
3458 if (0 != status)
3459 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460 return -EINVAL;
3461 }
Dino Myclee8843b32014-07-04 14:21:45 +05303462 /* check the EXTScan Capability */
3463 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3464 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3465 {
3466 hddLog(VOS_TRACE_LEVEL_ERROR,
3467 FL("EXTScan not enabled/supported by Firmware"));
3468 return -EINVAL;
3469 }
3470
Dino Mycle6fb96c12014-06-10 11:52:40 +05303471 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3472 data, dataLen,
3473 wlan_hdd_extscan_config_policy)) {
3474 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3475 return -EINVAL;
3476 }
3477
3478 /* Parse and fetch request Id */
3479 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3480 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3481 return -EINVAL;
3482 }
3483
Dino Myclee8843b32014-07-04 14:21:45 +05303484 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303485 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303486 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303487
Dino Myclee8843b32014-07-04 14:21:45 +05303488 reqMsg.sessionId = pAdapter->sessionId;
3489 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303490
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303491 vos_spin_lock_acquire(&hdd_context_lock);
3492 context = &pHddCtx->ext_scan_context;
3493 context->request_id = reqMsg.requestId;
3494 INIT_COMPLETION(context->response_event);
3495 vos_spin_lock_release(&hdd_context_lock);
3496
Dino Myclee8843b32014-07-04 14:21:45 +05303497 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303498 if (!HAL_STATUS_SUCCESS(status)) {
3499 hddLog(VOS_TRACE_LEVEL_ERROR,
3500 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303501 return -EINVAL;
3502 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303503
3504 rc = wait_for_completion_timeout(&context->response_event,
3505 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3506 if (!rc) {
3507 hddLog(LOGE, FL("Target response timed out"));
3508 return -ETIMEDOUT;
3509 }
3510
3511 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3512 if (ret)
3513 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3514
3515 return ret;
3516
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303517 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303518 return 0;
3519}
3520
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303521static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3522 struct wireless_dev *wdev,
3523 const void *data, int dataLen)
3524{
3525 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303526
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303527 vos_ssr_protect(__func__);
3528 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3529 vos_ssr_unprotect(__func__);
3530
3531 return ret;
3532}
3533
3534static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3535 struct wireless_dev *wdev,
3536 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303537{
Dino Myclee8843b32014-07-04 14:21:45 +05303538 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303539 struct net_device *dev = wdev->netdev;
3540 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3541 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3542 struct nlattr
3543 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3544 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303545 struct hdd_ext_scan_context *context;
3546 unsigned long rc;
3547 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303548
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303549 ENTER();
3550
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303551 if (VOS_FTM_MODE == hdd_get_conparam()) {
3552 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3553 return -EINVAL;
3554 }
3555
Dino Mycle6fb96c12014-06-10 11:52:40 +05303556 status = wlan_hdd_validate_context(pHddCtx);
3557 if (0 != status)
3558 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303559 return -EINVAL;
3560 }
Dino Myclee8843b32014-07-04 14:21:45 +05303561 /* check the EXTScan Capability */
3562 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3563 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3564 {
3565 hddLog(VOS_TRACE_LEVEL_ERROR,
3566 FL("EXTScan not enabled/supported by Firmware"));
3567 return -EINVAL;
3568 }
3569
Dino Mycle6fb96c12014-06-10 11:52:40 +05303570 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3571 data, dataLen,
3572 wlan_hdd_extscan_config_policy)) {
3573 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3574 return -EINVAL;
3575 }
3576 /* Parse and fetch request Id */
3577 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3578 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3579 return -EINVAL;
3580 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303581
Dino Myclee8843b32014-07-04 14:21:45 +05303582 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303583 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3584
Dino Myclee8843b32014-07-04 14:21:45 +05303585 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303586
Dino Myclee8843b32014-07-04 14:21:45 +05303587 reqMsg.sessionId = pAdapter->sessionId;
3588 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303589
3590 /* Parse and fetch flush parameter */
3591 if (!tb
3592 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3593 {
3594 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3595 goto failed;
3596 }
Dino Myclee8843b32014-07-04 14:21:45 +05303597 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303598 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3599
Dino Myclee8843b32014-07-04 14:21:45 +05303600 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303601
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303602 spin_lock(&hdd_context_lock);
3603 context = &pHddCtx->ext_scan_context;
3604 context->request_id = reqMsg.requestId;
3605 context->ignore_cached_results = false;
3606 INIT_COMPLETION(context->response_event);
3607 spin_unlock(&hdd_context_lock);
3608
Dino Myclee8843b32014-07-04 14:21:45 +05303609 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303610 if (!HAL_STATUS_SUCCESS(status)) {
3611 hddLog(VOS_TRACE_LEVEL_ERROR,
3612 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303613 return -EINVAL;
3614 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303615
3616 rc = wait_for_completion_timeout(&context->response_event,
3617 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3618 if (!rc) {
3619 hddLog(LOGE, FL("Target response timed out"));
3620 retval = -ETIMEDOUT;
3621 spin_lock(&hdd_context_lock);
3622 context->ignore_cached_results = true;
3623 spin_unlock(&hdd_context_lock);
3624 } else {
3625 spin_lock(&hdd_context_lock);
3626 retval = context->response_status;
3627 spin_unlock(&hdd_context_lock);
3628 }
3629
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303630 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303631 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303632
3633failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303634 return -EINVAL;
3635}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303636static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3637 struct wireless_dev *wdev,
3638 const void *data, int dataLen)
3639{
3640 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303641
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303642 vos_ssr_protect(__func__);
3643 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3644 vos_ssr_unprotect(__func__);
3645
3646 return ret;
3647}
3648
3649static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303650 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303651 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303652{
3653 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3654 struct net_device *dev = wdev->netdev;
3655 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3656 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3657 struct nlattr
3658 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3659 struct nlattr
3660 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3661 struct nlattr *apTh;
3662 eHalStatus status;
3663 tANI_U8 i = 0;
3664 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303665 struct hdd_ext_scan_context *context;
3666 tANI_U32 request_id;
3667 unsigned long rc;
3668 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303669
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303670 ENTER();
3671
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303672 if (VOS_FTM_MODE == hdd_get_conparam()) {
3673 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3674 return -EINVAL;
3675 }
3676
Dino Mycle6fb96c12014-06-10 11:52:40 +05303677 status = wlan_hdd_validate_context(pHddCtx);
3678 if (0 != status)
3679 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303680 return -EINVAL;
3681 }
Dino Myclee8843b32014-07-04 14:21:45 +05303682 /* check the EXTScan Capability */
3683 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3684 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3685 {
3686 hddLog(VOS_TRACE_LEVEL_ERROR,
3687 FL("EXTScan not enabled/supported by Firmware"));
3688 return -EINVAL;
3689 }
3690
Dino Mycle6fb96c12014-06-10 11:52:40 +05303691 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3692 data, dataLen,
3693 wlan_hdd_extscan_config_policy)) {
3694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3695 return -EINVAL;
3696 }
3697
3698 /* Parse and fetch request Id */
3699 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3700 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3701 return -EINVAL;
3702 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303703 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3704 vos_mem_malloc(sizeof(*pReqMsg));
3705 if (!pReqMsg) {
3706 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3707 return -ENOMEM;
3708 }
3709
Dino Myclee8843b32014-07-04 14:21:45 +05303710
Dino Mycle6fb96c12014-06-10 11:52:40 +05303711 pReqMsg->requestId = nla_get_u32(
3712 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3713 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3714
3715 /* Parse and fetch number of APs */
3716 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3717 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3718 goto fail;
3719 }
3720
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303721 /* Parse and fetch lost ap sample size */
3722 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3723 hddLog(LOGE, FL("attr lost ap sample size failed"));
3724 goto fail;
3725 }
3726
3727 pReqMsg->lostBssidSampleSize = nla_get_u32(
3728 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3729 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3730
Dino Mycle6fb96c12014-06-10 11:52:40 +05303731 pReqMsg->sessionId = pAdapter->sessionId;
3732 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3733
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303734 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303735 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303736 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303737
3738 nla_for_each_nested(apTh,
3739 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3740 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3741 nla_data(apTh), nla_len(apTh),
3742 NULL)) {
3743 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3744 goto fail;
3745 }
3746
3747 /* Parse and fetch MAC address */
3748 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3749 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3750 goto fail;
3751 }
3752 memcpy(pReqMsg->ap[i].bssid, nla_data(
3753 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3754 sizeof(tSirMacAddr));
3755 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3756
3757 /* Parse and fetch low RSSI */
3758 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3759 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3760 goto fail;
3761 }
3762 pReqMsg->ap[i].low = nla_get_s32(
3763 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3764 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3765
3766 /* Parse and fetch high RSSI */
3767 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3769 goto fail;
3770 }
3771 pReqMsg->ap[i].high = nla_get_s32(
3772 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3773 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3774 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303775 i++;
3776 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303777
3778 context = &pHddCtx->ext_scan_context;
3779 spin_lock(&hdd_context_lock);
3780 INIT_COMPLETION(context->response_event);
3781 context->request_id = request_id = pReqMsg->requestId;
3782 spin_unlock(&hdd_context_lock);
3783
Dino Mycle6fb96c12014-06-10 11:52:40 +05303784 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3785 if (!HAL_STATUS_SUCCESS(status)) {
3786 hddLog(VOS_TRACE_LEVEL_ERROR,
3787 FL("sme_SetBssHotlist failed(err=%d)"), status);
3788 vos_mem_free(pReqMsg);
3789 return -EINVAL;
3790 }
3791
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303792 /* request was sent -- wait for the response */
3793 rc = wait_for_completion_timeout(&context->response_event,
3794 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3795
3796 if (!rc) {
3797 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3798 retval = -ETIMEDOUT;
3799 } else {
3800 spin_lock(&hdd_context_lock);
3801 if (context->request_id == request_id)
3802 retval = context->response_status;
3803 else
3804 retval = -EINVAL;
3805 spin_unlock(&hdd_context_lock);
3806 }
3807
Dino Myclee8843b32014-07-04 14:21:45 +05303808 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303809 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303810 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303811
3812fail:
3813 vos_mem_free(pReqMsg);
3814 return -EINVAL;
3815}
3816
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303817static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3818 struct wireless_dev *wdev,
3819 const void *data, int dataLen)
3820{
3821 int ret = 0;
3822
3823 vos_ssr_protect(__func__);
3824 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3825 dataLen);
3826 vos_ssr_unprotect(__func__);
3827
3828 return ret;
3829}
3830
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303831/*
3832 * define short names for the global vendor params
3833 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3834 */
3835#define PARAM_MAX \
3836QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3837#define PARAM_REQUEST_ID \
3838QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3839#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3840QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3841#define PARAMS_NUM_SSID \
3842QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3843#define THRESHOLD_PARAM \
3844QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3845#define PARAM_SSID \
3846QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3847#define PARAM_BAND \
3848QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3849#define PARAM_RSSI_LOW \
3850QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3851#define PARAM_RSSI_HIGH \
3852QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3853
3854/**
3855 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3856 * @wiphy: Pointer to wireless phy
3857 * @wdev: Pointer to wireless device
3858 * @data: Pointer to data
3859 * @data_len: Data length
3860 *
3861 * Return: 0 on success, negative errno on failure
3862 */
3863static int
3864__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3865 struct wireless_dev *wdev,
3866 const void *data,
3867 int data_len)
3868{
3869 tSirEXTScanSetSsidHotListReqParams *request;
3870 struct net_device *dev = wdev->netdev;
3871 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3872 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3873 struct nlattr *tb[PARAM_MAX + 1];
3874 struct nlattr *tb2[PARAM_MAX + 1];
3875 struct nlattr *ssids;
3876 struct hdd_ext_scan_context *context;
3877 uint32_t request_id;
3878 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3879 int ssid_len;
3880 eHalStatus status;
3881 int i, rem, retval;
3882 unsigned long rc;
3883
3884 ENTER();
3885
3886 if (VOS_FTM_MODE == hdd_get_conparam()) {
3887 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3888 return -EINVAL;
3889 }
3890
3891 retval = wlan_hdd_validate_context(hdd_ctx);
3892 if (0 != retval) {
3893 hddLog(LOGE, FL("HDD context is not valid"));
3894 return -EINVAL;
3895 }
3896
3897 /* check the EXTScan Capability */
3898 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
3899 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3900 {
3901 hddLog(VOS_TRACE_LEVEL_ERROR,
3902 FL("EXTScan not enabled/supported by Firmware"));
3903 return -EINVAL;
3904 }
3905
3906 if (nla_parse(tb, PARAM_MAX,
3907 data, data_len,
3908 wlan_hdd_extscan_config_policy)) {
3909 hddLog(LOGE, FL("Invalid ATTR"));
3910 return -EINVAL;
3911 }
3912
3913 request = vos_mem_malloc(sizeof(*request));
3914 if (!request) {
3915 hddLog(LOGE, FL("vos_mem_malloc failed"));
3916 return -ENOMEM;
3917 }
3918
3919 /* Parse and fetch request Id */
3920 if (!tb[PARAM_REQUEST_ID]) {
3921 hddLog(LOGE, FL("attr request id failed"));
3922 goto fail;
3923 }
3924
3925 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3926 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3927
3928 /* Parse and fetch lost SSID sample size */
3929 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3930 hddLog(LOGE, FL("attr number of Ssid failed"));
3931 goto fail;
3932 }
3933 request->lost_ssid_sample_size =
3934 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3935 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3936 request->lost_ssid_sample_size);
3937
3938 /* Parse and fetch number of hotlist SSID */
3939 if (!tb[PARAMS_NUM_SSID]) {
3940 hddLog(LOGE, FL("attr number of Ssid failed"));
3941 goto fail;
3942 }
3943 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3944 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3945
3946 request->session_id = adapter->sessionId;
3947 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3948
3949 i = 0;
3950 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3951 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3952 hddLog(LOGE,
3953 FL("Too Many SSIDs, %d exceeds %d"),
3954 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3955 break;
3956 }
3957 if (nla_parse(tb2, PARAM_MAX,
3958 nla_data(ssids), nla_len(ssids),
3959 wlan_hdd_extscan_config_policy)) {
3960 hddLog(LOGE, FL("nla_parse failed"));
3961 goto fail;
3962 }
3963
3964 /* Parse and fetch SSID */
3965 if (!tb2[PARAM_SSID]) {
3966 hddLog(LOGE, FL("attr ssid failed"));
3967 goto fail;
3968 }
3969 nla_memcpy(ssid_string,
3970 tb2[PARAM_SSID],
3971 sizeof(ssid_string));
3972 hddLog(LOG1, FL("SSID %s"),
3973 ssid_string);
3974 ssid_len = strlen(ssid_string);
3975 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
3976 request->ssid[i].ssid.length = ssid_len;
3977 request->ssid[i].ssid.ssId[ssid_len] = '\0';
3978 hddLog(LOG1, FL("After copying SSID %s"),
3979 request->ssid[i].ssid.ssId);
3980 hddLog(LOG1, FL("After copying length: %d"),
3981 ssid_len);
3982
3983 /* Parse and fetch low RSSI */
3984 if (!tb2[PARAM_BAND]) {
3985 hddLog(LOGE, FL("attr band failed"));
3986 goto fail;
3987 }
3988 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
3989 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
3990
3991 /* Parse and fetch low RSSI */
3992 if (!tb2[PARAM_RSSI_LOW]) {
3993 hddLog(LOGE, FL("attr low RSSI failed"));
3994 goto fail;
3995 }
3996 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
3997 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
3998
3999 /* Parse and fetch high RSSI */
4000 if (!tb2[PARAM_RSSI_HIGH]) {
4001 hddLog(LOGE, FL("attr high RSSI failed"));
4002 goto fail;
4003 }
4004 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4005 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4006 i++;
4007 }
4008
4009 context = &hdd_ctx->ext_scan_context;
4010 spin_lock(&hdd_context_lock);
4011 INIT_COMPLETION(context->response_event);
4012 context->request_id = request_id = request->request_id;
4013 spin_unlock(&hdd_context_lock);
4014
4015 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4016 if (!HAL_STATUS_SUCCESS(status)) {
4017 hddLog(LOGE,
4018 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4019 goto fail;
4020 }
4021
4022 vos_mem_free(request);
4023
4024 /* request was sent -- wait for the response */
4025 rc = wait_for_completion_timeout(&context->response_event,
4026 msecs_to_jiffies
4027 (WLAN_WAIT_TIME_EXTSCAN));
4028 if (!rc) {
4029 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4030 retval = -ETIMEDOUT;
4031 } else {
4032 spin_lock(&hdd_context_lock);
4033 if (context->request_id == request_id)
4034 retval = context->response_status;
4035 else
4036 retval = -EINVAL;
4037 spin_unlock(&hdd_context_lock);
4038 }
4039
4040 return retval;
4041
4042fail:
4043 vos_mem_free(request);
4044 return -EINVAL;
4045}
4046
4047/*
4048 * done with short names for the global vendor params
4049 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4050 */
4051#undef PARAM_MAX
4052#undef PARAM_REQUEST_ID
4053#undef PARAMS_NUM_SSID
4054#undef THRESHOLD_PARAM
4055#undef PARAM_SSID
4056#undef PARAM_BAND
4057#undef PARAM_RSSI_LOW
4058#undef PARAM_RSSI_HIGH
4059
4060static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4061 struct wireless_dev *wdev,
4062 const void *data, int dataLen)
4063{
4064 int ret = 0;
4065
4066 vos_ssr_protect(__func__);
4067 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4068 dataLen);
4069 vos_ssr_unprotect(__func__);
4070
4071 return ret;
4072}
4073
4074static int
4075__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4076 struct wireless_dev *wdev,
4077 const void *data,
4078 int data_len)
4079{
4080 tSirEXTScanResetSsidHotlistReqParams request;
4081 struct net_device *dev = wdev->netdev;
4082 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4083 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4084 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4085 struct hdd_ext_scan_context *context;
4086 uint32_t request_id;
4087 eHalStatus status;
4088 int retval;
4089 unsigned long rc;
4090
4091 ENTER();
4092
4093 if (VOS_FTM_MODE == hdd_get_conparam()) {
4094 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4095 return -EINVAL;
4096 }
4097
4098 retval = wlan_hdd_validate_context(hdd_ctx);
4099 if (0 != retval) {
4100 hddLog(LOGE, FL("HDD context is not valid"));
4101 return -EINVAL;
4102 }
4103
4104 /* check the EXTScan Capability */
4105 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
4106 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4107 {
4108 hddLog(LOGE,
4109 FL("EXTScan not enabled/supported by Firmware"));
4110 return -EINVAL;
4111 }
4112
4113 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4114 data, data_len,
4115 wlan_hdd_extscan_config_policy)) {
4116 hddLog(LOGE, FL("Invalid ATTR"));
4117 return -EINVAL;
4118 }
4119
4120 /* Parse and fetch request Id */
4121 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4122 hddLog(LOGE, FL("attr request id failed"));
4123 return -EINVAL;
4124 }
4125
4126 request.requestId = nla_get_u32(
4127 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4128 request.sessionId = adapter->sessionId;
4129 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4130 request.sessionId);
4131
4132 context = &hdd_ctx->ext_scan_context;
4133 spin_lock(&hdd_context_lock);
4134 INIT_COMPLETION(context->response_event);
4135 context->request_id = request_id = request.requestId;
4136 spin_unlock(&hdd_context_lock);
4137
4138 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4139 if (!HAL_STATUS_SUCCESS(status)) {
4140 hddLog(LOGE,
4141 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4142 return -EINVAL;
4143 }
4144
4145 /* request was sent -- wait for the response */
4146 rc = wait_for_completion_timeout(&context->response_event,
4147 msecs_to_jiffies
4148 (WLAN_WAIT_TIME_EXTSCAN));
4149 if (!rc) {
4150 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4151 retval = -ETIMEDOUT;
4152 } else {
4153 spin_lock(&hdd_context_lock);
4154 if (context->request_id == request_id)
4155 retval = context->response_status;
4156 else
4157 retval = -EINVAL;
4158 spin_unlock(&hdd_context_lock);
4159 }
4160
4161 return retval;
4162}
4163
4164static int
4165wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4166 struct wireless_dev *wdev,
4167 const void *data,
4168 int data_len)
4169{
4170 int ret;
4171
4172 vos_ssr_protect(__func__);
4173 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4174 data, data_len);
4175 vos_ssr_unprotect(__func__);
4176
4177 return ret;
4178}
4179
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304180static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304181 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304182 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304183{
4184 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4185 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4186 tANI_U8 numChannels = 0;
4187 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304188 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304189 tWifiBand wifiBand;
4190 eHalStatus status;
4191 struct sk_buff *replySkb;
4192 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304193 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304194
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304195 ENTER();
4196
Dino Mycle6fb96c12014-06-10 11:52:40 +05304197 status = wlan_hdd_validate_context(pHddCtx);
4198 if (0 != status)
4199 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304200 return -EINVAL;
4201 }
Dino Myclee8843b32014-07-04 14:21:45 +05304202
Dino Mycle6fb96c12014-06-10 11:52:40 +05304203 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4204 data, dataLen,
4205 wlan_hdd_extscan_config_policy)) {
4206 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4207 return -EINVAL;
4208 }
4209
4210 /* Parse and fetch request Id */
4211 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4212 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4213 return -EINVAL;
4214 }
4215 requestId = nla_get_u32(
4216 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4217 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4218
4219 /* Parse and fetch wifi band */
4220 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4221 {
4222 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4223 return -EINVAL;
4224 }
4225 wifiBand = nla_get_u32(
4226 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4227 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4228
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304229 /* Parse and fetch max channels */
4230 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4231 {
4232 hddLog(LOGE, FL("attr max channels failed"));
4233 return -EINVAL;
4234 }
4235 maxChannels = nla_get_u32(
4236 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4237 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4238
Dino Mycle6fb96c12014-06-10 11:52:40 +05304239 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
4240 wifiBand, ChannelList,
4241 &numChannels);
4242 if (eHAL_STATUS_SUCCESS != status) {
4243 hddLog(VOS_TRACE_LEVEL_ERROR,
4244 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4245 return -EINVAL;
4246 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304247
4248 numChannels = VOS_MIN(numChannels, maxChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304249 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304250
Dino Mycle6fb96c12014-06-10 11:52:40 +05304251 for (i = 0; i < numChannels; i++)
4252 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
4253
4254 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4255 sizeof(u32) * numChannels +
4256 NLMSG_HDRLEN);
4257
4258 if (!replySkb) {
4259 hddLog(VOS_TRACE_LEVEL_ERROR,
4260 FL("valid channels: buffer alloc fail"));
4261 return -EINVAL;
4262 }
4263 if (nla_put_u32(replySkb,
4264 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
4265 numChannels) ||
4266 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
4267 sizeof(u32) * numChannels, ChannelList)) {
4268
4269 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4270 kfree_skb(replySkb);
4271 return -EINVAL;
4272 }
4273
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304274 ret = cfg80211_vendor_cmd_reply(replySkb);
4275
4276 EXIT();
4277 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304278}
4279
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304280static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4281 struct wireless_dev *wdev,
4282 const void *data, int dataLen)
4283{
4284 int ret = 0;
4285
4286 vos_ssr_protect(__func__);
4287 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4288 dataLen);
4289 vos_ssr_unprotect(__func__);
4290
4291 return ret;
4292}
4293
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304294static int hdd_extscan_start_fill_bucket_channel_spec(
4295 hdd_context_t *pHddCtx,
4296 tpSirEXTScanStartReqParams pReqMsg,
4297 struct nlattr **tb)
4298{
4299 struct nlattr *bucket[
4300 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4301 struct nlattr *channel[
4302 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4303 struct nlattr *buckets;
4304 struct nlattr *channels;
4305 int rem1, rem2;
4306 eHalStatus status;
4307 tANI_U8 bktIndex, j, numChannels;
4308 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4309 tANI_U32 passive_max_chn_time, active_max_chn_time;
4310
4311 bktIndex = 0;
4312
4313 nla_for_each_nested(buckets,
4314 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4315 if (nla_parse(bucket,
4316 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4317 nla_data(buckets), nla_len(buckets), NULL)) {
4318 hddLog(LOGE, FL("nla_parse failed"));
4319 return -EINVAL;
4320 }
4321
4322 /* Parse and fetch bucket spec */
4323 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4324 hddLog(LOGE, FL("attr bucket index failed"));
4325 return -EINVAL;
4326 }
4327 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4328 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4329 hddLog(LOG1, FL("Bucket spec Index %d"),
4330 pReqMsg->buckets[bktIndex].bucket);
4331
4332 /* Parse and fetch wifi band */
4333 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4334 hddLog(LOGE, FL("attr wifi band failed"));
4335 return -EINVAL;
4336 }
4337 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4338 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4339 hddLog(LOG1, FL("Wifi band %d"),
4340 pReqMsg->buckets[bktIndex].band);
4341
4342 /* Parse and fetch period */
4343 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4344 hddLog(LOGE, FL("attr period failed"));
4345 return -EINVAL;
4346 }
4347 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4348 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4349 hddLog(LOG1, FL("period %d"),
4350 pReqMsg->buckets[bktIndex].period);
4351
4352 /* Parse and fetch report events */
4353 if (!bucket[
4354 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4355 hddLog(LOGE, FL("attr report events failed"));
4356 return -EINVAL;
4357 }
4358 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4359 bucket[
4360 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4361 hddLog(LOG1, FL("report events %d"),
4362 pReqMsg->buckets[bktIndex].reportEvents);
4363
4364 /* Parse and fetch max period */
4365 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4366 hddLog(LOGE, FL("attr max period failed"));
4367 return -EINVAL;
4368 }
4369 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4370 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4371 hddLog(LOG1, FL("max period %u"),
4372 pReqMsg->buckets[bktIndex].max_period);
4373
4374 /* Parse and fetch exponent */
4375 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4376 hddLog(LOGE, FL("attr exponent failed"));
4377 return -EINVAL;
4378 }
4379 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4380 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4381 hddLog(LOG1, FL("exponent %u"),
4382 pReqMsg->buckets[bktIndex].exponent);
4383
4384 /* Parse and fetch step count */
4385 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4386 hddLog(LOGE, FL("attr step count failed"));
4387 return -EINVAL;
4388 }
4389 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4390 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4391 hddLog(LOG1, FL("Step count %u"),
4392 pReqMsg->buckets[bktIndex].step_count);
4393
4394 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4395 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4396
4397 /* Framework shall pass the channel list if the input WiFi band is
4398 * WIFI_BAND_UNSPECIFIED.
4399 * If the input WiFi band is specified (any value other than
4400 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4401 */
4402 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4403 numChannels = 0;
4404 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4405 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4406 pReqMsg->buckets[bktIndex].band,
4407 chanList, &numChannels);
4408 if (!HAL_STATUS_SUCCESS(status)) {
4409 hddLog(LOGE,
4410 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4411 status);
4412 return -EINVAL;
4413 }
4414
4415 pReqMsg->buckets[bktIndex].numChannels =
4416 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4417 hddLog(LOG1, FL("Num channels %d"),
4418 pReqMsg->buckets[bktIndex].numChannels);
4419
4420 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4421 j++) {
4422 pReqMsg->buckets[bktIndex].channels[j].channel =
4423 chanList[j];
4424 pReqMsg->buckets[bktIndex].channels[j].
4425 chnlClass = 0;
4426 if (CSR_IS_CHANNEL_DFS(
4427 vos_freq_to_chan(chanList[j]))) {
4428 pReqMsg->buckets[bktIndex].channels[j].
4429 passive = 1;
4430 pReqMsg->buckets[bktIndex].channels[j].
4431 dwellTimeMs = passive_max_chn_time;
4432 } else {
4433 pReqMsg->buckets[bktIndex].channels[j].
4434 passive = 0;
4435 pReqMsg->buckets[bktIndex].channels[j].
4436 dwellTimeMs = active_max_chn_time;
4437 }
4438
4439 hddLog(LOG1,
4440 "Channel %u Passive %u Dwell time %u ms",
4441 pReqMsg->buckets[bktIndex].channels[j].channel,
4442 pReqMsg->buckets[bktIndex].channels[j].passive,
4443 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4444 }
4445
4446 bktIndex++;
4447 continue;
4448 }
4449
4450 /* Parse and fetch number of channels */
4451 if (!bucket[
4452 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4453 hddLog(LOGE, FL("attr num channels failed"));
4454 return -EINVAL;
4455 }
4456
4457 pReqMsg->buckets[bktIndex].numChannels =
4458 nla_get_u32(bucket[
4459 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4460 hddLog(LOG1, FL("num channels %d"),
4461 pReqMsg->buckets[bktIndex].numChannels);
4462
4463 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4464 hddLog(LOGE, FL("attr channel spec failed"));
4465 return -EINVAL;
4466 }
4467
4468 j = 0;
4469 nla_for_each_nested(channels,
4470 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4471 if (nla_parse(channel,
4472 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4473 nla_data(channels), nla_len(channels),
4474 wlan_hdd_extscan_config_policy)) {
4475 hddLog(LOGE, FL("nla_parse failed"));
4476 return -EINVAL;
4477 }
4478
4479 /* Parse and fetch channel */
4480 if (!channel[
4481 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4482 hddLog(LOGE, FL("attr channel failed"));
4483 return -EINVAL;
4484 }
4485 pReqMsg->buckets[bktIndex].channels[j].channel =
4486 nla_get_u32(channel[
4487 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4488 hddLog(LOG1, FL("channel %u"),
4489 pReqMsg->buckets[bktIndex].channels[j].channel);
4490
4491 /* Parse and fetch dwell time */
4492 if (!channel[
4493 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4494 hddLog(LOGE, FL("attr dwelltime failed"));
4495 return -EINVAL;
4496 }
4497 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4498 nla_get_u32(channel[
4499 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4500
4501 hddLog(LOG1, FL("Dwell time (%u ms)"),
4502 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4503
4504
4505 /* Parse and fetch channel spec passive */
4506 if (!channel[
4507 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4508 hddLog(LOGE,
4509 FL("attr channel spec passive failed"));
4510 return -EINVAL;
4511 }
4512 pReqMsg->buckets[bktIndex].channels[j].passive =
4513 nla_get_u8(channel[
4514 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4515 hddLog(LOG1, FL("Chnl spec passive %u"),
4516 pReqMsg->buckets[bktIndex].channels[j].passive);
4517
4518 j++;
4519 }
4520
4521 bktIndex++;
4522 }
4523
4524 return 0;
4525}
4526
4527
4528/*
4529 * define short names for the global vendor params
4530 * used by wlan_hdd_cfg80211_extscan_start()
4531 */
4532#define PARAM_MAX \
4533QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4534#define PARAM_REQUEST_ID \
4535QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4536#define PARAM_BASE_PERIOD \
4537QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4538#define PARAM_MAX_AP_PER_SCAN \
4539QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4540#define PARAM_RPT_THRHLD_PERCENT \
4541QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4542#define PARAM_RPT_THRHLD_NUM_SCANS \
4543QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4544#define PARAM_NUM_BUCKETS \
4545QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4546
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304547static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304548 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304549 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304550{
Dino Myclee8843b32014-07-04 14:21:45 +05304551 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304552 struct net_device *dev = wdev->netdev;
4553 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4554 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4555 struct nlattr *tb[PARAM_MAX + 1];
4556 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304557 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304558 tANI_U32 request_id;
4559 struct hdd_ext_scan_context *context;
4560 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304561
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304562 ENTER();
4563
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304564 if (VOS_FTM_MODE == hdd_get_conparam()) {
4565 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4566 return -EINVAL;
4567 }
4568
Dino Mycle6fb96c12014-06-10 11:52:40 +05304569 status = wlan_hdd_validate_context(pHddCtx);
4570 if (0 != status)
4571 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304572 return -EINVAL;
4573 }
Dino Myclee8843b32014-07-04 14:21:45 +05304574 /* check the EXTScan Capability */
4575 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4576 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4577 {
4578 hddLog(VOS_TRACE_LEVEL_ERROR,
4579 FL("EXTScan not enabled/supported by Firmware"));
4580 return -EINVAL;
4581 }
4582
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304583 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304584 data, dataLen,
4585 wlan_hdd_extscan_config_policy)) {
4586 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4587 return -EINVAL;
4588 }
4589
4590 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304591 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304592 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4593 return -EINVAL;
4594 }
4595
Dino Myclee8843b32014-07-04 14:21:45 +05304596 pReqMsg = (tpSirEXTScanStartReqParams)
4597 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304598 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304599 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4600 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304601 }
4602
4603 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304604 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304605 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4606
4607 pReqMsg->sessionId = pAdapter->sessionId;
4608 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4609
4610 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304611 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304612 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4613 goto fail;
4614 }
4615 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304616 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304617 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4618 pReqMsg->basePeriod);
4619
4620 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304621 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304622 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4623 goto fail;
4624 }
4625 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304626 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304627 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4628 pReqMsg->maxAPperScan);
4629
4630 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304631 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304632 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4633 goto fail;
4634 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304635 pReqMsg->reportThresholdPercent = nla_get_u8(
4636 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304637 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304638 pReqMsg->reportThresholdPercent);
4639
4640 /* Parse and fetch report threshold num scans */
4641 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4642 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4643 goto fail;
4644 }
4645 pReqMsg->reportThresholdNumScans = nla_get_u8(
4646 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4647 hddLog(LOG1, FL("Report Threshold num scans %d"),
4648 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304649
4650 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304651 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304652 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4653 goto fail;
4654 }
4655 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304656 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304657 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4658 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4659 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4660 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4661 }
4662 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4663 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304664
Dino Mycle6fb96c12014-06-10 11:52:40 +05304665 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4666 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4667 goto fail;
4668 }
4669
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304670 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304671
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304672 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4673 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304674
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304675 context = &pHddCtx->ext_scan_context;
4676 spin_lock(&hdd_context_lock);
4677 INIT_COMPLETION(context->response_event);
4678 context->request_id = request_id = pReqMsg->requestId;
4679 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304680
Dino Mycle6fb96c12014-06-10 11:52:40 +05304681 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4682 if (!HAL_STATUS_SUCCESS(status)) {
4683 hddLog(VOS_TRACE_LEVEL_ERROR,
4684 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304685 goto fail;
4686 }
4687
4688 /* request was sent -- wait for the response */
4689 rc = wait_for_completion_timeout(&context->response_event,
4690 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4691
4692 if (!rc) {
4693 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4694 retval = -ETIMEDOUT;
4695 } else {
4696 spin_lock(&hdd_context_lock);
4697 if (context->request_id == request_id)
4698 retval = context->response_status;
4699 else
4700 retval = -EINVAL;
4701 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304702 }
4703
Dino Myclee8843b32014-07-04 14:21:45 +05304704 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304705 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304706 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304707
4708fail:
4709 vos_mem_free(pReqMsg);
4710 return -EINVAL;
4711}
4712
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304713/*
4714 * done with short names for the global vendor params
4715 * used by wlan_hdd_cfg80211_extscan_start()
4716 */
4717#undef PARAM_MAX
4718#undef PARAM_REQUEST_ID
4719#undef PARAM_BASE_PERIOD
4720#undef PARAMS_MAX_AP_PER_SCAN
4721#undef PARAMS_RPT_THRHLD_PERCENT
4722#undef PARAMS_RPT_THRHLD_NUM_SCANS
4723#undef PARAMS_NUM_BUCKETS
4724
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304725static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4726 struct wireless_dev *wdev,
4727 const void *data, int dataLen)
4728{
4729 int ret = 0;
4730
4731 vos_ssr_protect(__func__);
4732 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4733 vos_ssr_unprotect(__func__);
4734
4735 return ret;
4736}
4737
4738static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304739 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304740 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304741{
Dino Myclee8843b32014-07-04 14:21:45 +05304742 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304743 struct net_device *dev = wdev->netdev;
4744 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4745 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4746 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4747 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304748 int retval;
4749 unsigned long rc;
4750 struct hdd_ext_scan_context *context;
4751 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304752
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304753 ENTER();
4754
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304755 if (VOS_FTM_MODE == hdd_get_conparam()) {
4756 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4757 return -EINVAL;
4758 }
4759
Dino Mycle6fb96c12014-06-10 11:52:40 +05304760 status = wlan_hdd_validate_context(pHddCtx);
4761 if (0 != status)
4762 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304763 return -EINVAL;
4764 }
Dino Myclee8843b32014-07-04 14:21:45 +05304765 /* check the EXTScan Capability */
4766 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4767 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4768 {
4769 hddLog(VOS_TRACE_LEVEL_ERROR,
4770 FL("EXTScan not enabled/supported by Firmware"));
4771 return -EINVAL;
4772 }
4773
Dino Mycle6fb96c12014-06-10 11:52:40 +05304774 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4775 data, dataLen,
4776 wlan_hdd_extscan_config_policy)) {
4777 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4778 return -EINVAL;
4779 }
4780
4781 /* Parse and fetch request Id */
4782 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4784 return -EINVAL;
4785 }
4786
Dino Myclee8843b32014-07-04 14:21:45 +05304787 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304788 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304789 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304790
Dino Myclee8843b32014-07-04 14:21:45 +05304791 reqMsg.sessionId = pAdapter->sessionId;
4792 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304793
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304794 context = &pHddCtx->ext_scan_context;
4795 spin_lock(&hdd_context_lock);
4796 INIT_COMPLETION(context->response_event);
4797 context->request_id = request_id = reqMsg.sessionId;
4798 spin_unlock(&hdd_context_lock);
4799
Dino Myclee8843b32014-07-04 14:21:45 +05304800 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304801 if (!HAL_STATUS_SUCCESS(status)) {
4802 hddLog(VOS_TRACE_LEVEL_ERROR,
4803 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304804 return -EINVAL;
4805 }
4806
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304807 /* request was sent -- wait for the response */
4808 rc = wait_for_completion_timeout(&context->response_event,
4809 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4810
4811 if (!rc) {
4812 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4813 retval = -ETIMEDOUT;
4814 } else {
4815 spin_lock(&hdd_context_lock);
4816 if (context->request_id == request_id)
4817 retval = context->response_status;
4818 else
4819 retval = -EINVAL;
4820 spin_unlock(&hdd_context_lock);
4821 }
4822
4823 return retval;
4824
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304825 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304826 return 0;
4827}
4828
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304829static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4830 struct wireless_dev *wdev,
4831 const void *data, int dataLen)
4832{
4833 int ret = 0;
4834
4835 vos_ssr_protect(__func__);
4836 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4837 vos_ssr_unprotect(__func__);
4838
4839 return ret;
4840}
4841
4842static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304843 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304844 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304845{
Dino Myclee8843b32014-07-04 14:21:45 +05304846 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304847 struct net_device *dev = wdev->netdev;
4848 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4849 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4850 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4851 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304852 struct hdd_ext_scan_context *context;
4853 tANI_U32 request_id;
4854 unsigned long rc;
4855 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304856
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304857 ENTER();
4858
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304859 if (VOS_FTM_MODE == hdd_get_conparam()) {
4860 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4861 return -EINVAL;
4862 }
4863
Dino Mycle6fb96c12014-06-10 11:52:40 +05304864 status = wlan_hdd_validate_context(pHddCtx);
4865 if (0 != status)
4866 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304867 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304868 return -EINVAL;
4869 }
Dino Myclee8843b32014-07-04 14:21:45 +05304870 /* check the EXTScan Capability */
4871 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4872 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4873 {
4874 hddLog(VOS_TRACE_LEVEL_ERROR,
4875 FL("EXTScan not enabled/supported by Firmware"));
4876 return -EINVAL;
4877 }
4878
Dino Mycle6fb96c12014-06-10 11:52:40 +05304879 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4880 data, dataLen,
4881 wlan_hdd_extscan_config_policy)) {
4882 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4883 return -EINVAL;
4884 }
4885
4886 /* Parse and fetch request Id */
4887 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4889 return -EINVAL;
4890 }
4891
Dino Myclee8843b32014-07-04 14:21:45 +05304892 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304893 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304894 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304895
Dino Myclee8843b32014-07-04 14:21:45 +05304896 reqMsg.sessionId = pAdapter->sessionId;
4897 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304898
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304899 context = &pHddCtx->ext_scan_context;
4900 spin_lock(&hdd_context_lock);
4901 INIT_COMPLETION(context->response_event);
4902 context->request_id = request_id = reqMsg.requestId;
4903 spin_unlock(&hdd_context_lock);
4904
Dino Myclee8843b32014-07-04 14:21:45 +05304905 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304906 if (!HAL_STATUS_SUCCESS(status)) {
4907 hddLog(VOS_TRACE_LEVEL_ERROR,
4908 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304909 return -EINVAL;
4910 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304911
4912 /* request was sent -- wait for the response */
4913 rc = wait_for_completion_timeout(&context->response_event,
4914 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4915 if (!rc) {
4916 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4917 retval = -ETIMEDOUT;
4918 } else {
4919 spin_lock(&hdd_context_lock);
4920 if (context->request_id == request_id)
4921 retval = context->response_status;
4922 else
4923 retval = -EINVAL;
4924 spin_unlock(&hdd_context_lock);
4925 }
4926
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304927 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304928 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304929}
4930
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304931static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4932 struct wireless_dev *wdev,
4933 const void *data, int dataLen)
4934{
4935 int ret = 0;
4936
4937 vos_ssr_protect(__func__);
4938 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4939 vos_ssr_unprotect(__func__);
4940
4941 return ret;
4942}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304943#endif /* WLAN_FEATURE_EXTSCAN */
4944
Atul Mittal115287b2014-07-08 13:26:33 +05304945/*EXT TDLS*/
4946static const struct nla_policy
4947wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4948{
4949 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4950 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4951 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4952 {.type = NLA_S32 },
4953 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4954 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4955
4956};
4957
4958static const struct nla_policy
4959wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4960{
4961 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4962
4963};
4964
4965static const struct nla_policy
4966wlan_hdd_tdls_config_state_change_policy[
4967 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4968{
4969 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4970 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4971 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304972 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4973 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4974 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304975
4976};
4977
4978static const struct nla_policy
4979wlan_hdd_tdls_config_get_status_policy[
4980 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4981{
4982 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4983 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4984 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304985 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4986 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4987 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304988
4989};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304990
4991static const struct nla_policy
4992wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4993{
4994 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4995};
4996
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304997static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304998 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304999 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305000 int data_len)
5001{
5002
5003 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5004 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5005
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305006 ENTER();
5007
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305008 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305009 return -EINVAL;
5010 }
5011 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305012 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305013 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305014 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305015 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305016 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305017 return -ENOTSUPP;
5018 }
5019
5020 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5021 data, data_len, wlan_hdd_mac_config)) {
5022 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5023 return -EINVAL;
5024 }
5025
5026 /* Parse and fetch mac address */
5027 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5028 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5029 return -EINVAL;
5030 }
5031
5032 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5033 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5034 VOS_MAC_ADDR_LAST_3_BYTES);
5035
Siddharth Bhal76972212014-10-15 16:22:51 +05305036 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5037
5038 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305039 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5040 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305041 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5042 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5043 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5044 {
5045 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5046 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5047 VOS_MAC_ADDRESS_LEN);
5048 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305049 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305050
Siddharth Bhal76972212014-10-15 16:22:51 +05305051 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
5052 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305053 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
5054 }
5055
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305056 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305057 return 0;
5058}
5059
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305060static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5061 struct wireless_dev *wdev,
5062 const void *data,
5063 int data_len)
5064{
5065 int ret = 0;
5066
5067 vos_ssr_protect(__func__);
5068 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5069 vos_ssr_unprotect(__func__);
5070
5071 return ret;
5072}
5073
5074static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305075 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305076 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305077 int data_len)
5078{
5079 u8 peer[6] = {0};
5080 struct net_device *dev = wdev->netdev;
5081 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5082 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5083 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5084 eHalStatus ret;
5085 tANI_S32 state;
5086 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305087 tANI_S32 global_operating_class = 0;
5088 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305089 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305090 int retVal;
5091
5092 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305093
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305094 if (!pAdapter) {
5095 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5096 return -EINVAL;
5097 }
5098
Atul Mittal115287b2014-07-08 13:26:33 +05305099 ret = wlan_hdd_validate_context(pHddCtx);
5100 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305102 return -EINVAL;
5103 }
5104 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305105 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305106 return -ENOTSUPP;
5107 }
5108 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5109 data, data_len,
5110 wlan_hdd_tdls_config_get_status_policy)) {
5111 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5112 return -EINVAL;
5113 }
5114
5115 /* Parse and fetch mac address */
5116 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5117 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5118 return -EINVAL;
5119 }
5120
5121 memcpy(peer, nla_data(
5122 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5123 sizeof(peer));
5124 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5125
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305126 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305127
Atul Mittal115287b2014-07-08 13:26:33 +05305128 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305129 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305130 NLMSG_HDRLEN);
5131
5132 if (!skb) {
5133 hddLog(VOS_TRACE_LEVEL_ERROR,
5134 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5135 return -EINVAL;
5136 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305137 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 +05305138 reason,
5139 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305140 global_operating_class,
5141 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305142 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305143 if (nla_put_s32(skb,
5144 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5145 state) ||
5146 nla_put_s32(skb,
5147 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5148 reason) ||
5149 nla_put_s32(skb,
5150 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5151 global_operating_class) ||
5152 nla_put_s32(skb,
5153 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5154 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305155
5156 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5157 goto nla_put_failure;
5158 }
5159
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305160 retVal = cfg80211_vendor_cmd_reply(skb);
5161 EXIT();
5162 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305163
5164nla_put_failure:
5165 kfree_skb(skb);
5166 return -EINVAL;
5167}
5168
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305169static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5170 struct wireless_dev *wdev,
5171 const void *data,
5172 int data_len)
5173{
5174 int ret = 0;
5175
5176 vos_ssr_protect(__func__);
5177 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5178 vos_ssr_unprotect(__func__);
5179
5180 return ret;
5181}
5182
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305183static int wlan_hdd_cfg80211_exttdls_callback(
5184#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5185 const tANI_U8* mac,
5186#else
5187 tANI_U8* mac,
5188#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305189 tANI_S32 state,
5190 tANI_S32 reason,
5191 void *ctx)
5192{
5193 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305194 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305195 tANI_S32 global_operating_class = 0;
5196 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305197 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305198
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305199 ENTER();
5200
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305201 if (!pAdapter) {
5202 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5203 return -EINVAL;
5204 }
5205
5206 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305207 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305208 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305209 return -EINVAL;
5210 }
5211
5212 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305213 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305214 return -ENOTSUPP;
5215 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305216 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5217#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5218 NULL,
5219#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305220 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5221 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5222 GFP_KERNEL);
5223
5224 if (!skb) {
5225 hddLog(VOS_TRACE_LEVEL_ERROR,
5226 FL("cfg80211_vendor_event_alloc failed"));
5227 return -EINVAL;
5228 }
5229 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305230 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5231 reason,
5232 state,
5233 global_operating_class,
5234 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305235 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5236 MAC_ADDR_ARRAY(mac));
5237
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305238 if (nla_put(skb,
5239 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5240 VOS_MAC_ADDR_SIZE, mac) ||
5241 nla_put_s32(skb,
5242 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5243 state) ||
5244 nla_put_s32(skb,
5245 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5246 reason) ||
5247 nla_put_s32(skb,
5248 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5249 channel) ||
5250 nla_put_s32(skb,
5251 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5252 global_operating_class)
5253 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305254 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5255 goto nla_put_failure;
5256 }
5257
5258 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305259 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305260 return (0);
5261
5262nla_put_failure:
5263 kfree_skb(skb);
5264 return -EINVAL;
5265}
5266
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305267static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305268 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305269 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305270 int data_len)
5271{
5272 u8 peer[6] = {0};
5273 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305274 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5275 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5276 eHalStatus status;
5277 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305278 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305279 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305280
5281 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305282
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305283 if (!dev) {
5284 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5285 return -EINVAL;
5286 }
5287
5288 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5289 if (!pAdapter) {
5290 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5291 return -EINVAL;
5292 }
5293
Atul Mittal115287b2014-07-08 13:26:33 +05305294 status = wlan_hdd_validate_context(pHddCtx);
5295 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305296 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305297 return -EINVAL;
5298 }
5299 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305300 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305301 return -ENOTSUPP;
5302 }
5303 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5304 data, data_len,
5305 wlan_hdd_tdls_config_enable_policy)) {
5306 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5307 return -EINVAL;
5308 }
5309
5310 /* Parse and fetch mac address */
5311 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5312 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5313 return -EINVAL;
5314 }
5315
5316 memcpy(peer, nla_data(
5317 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5318 sizeof(peer));
5319 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5320
5321 /* Parse and fetch channel */
5322 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5324 return -EINVAL;
5325 }
5326 pReqMsg.channel = nla_get_s32(
5327 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5328 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5329
5330 /* Parse and fetch global operating class */
5331 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5332 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5333 return -EINVAL;
5334 }
5335 pReqMsg.global_operating_class = nla_get_s32(
5336 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5337 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5338 pReqMsg.global_operating_class);
5339
5340 /* Parse and fetch latency ms */
5341 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5342 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5343 return -EINVAL;
5344 }
5345 pReqMsg.max_latency_ms = nla_get_s32(
5346 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5347 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5348 pReqMsg.max_latency_ms);
5349
5350 /* Parse and fetch required bandwidth kbps */
5351 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5352 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5353 return -EINVAL;
5354 }
5355
5356 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5357 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5358 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5359 pReqMsg.min_bandwidth_kbps);
5360
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305361 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305362 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305363 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305364 wlan_hdd_cfg80211_exttdls_callback);
5365
5366 EXIT();
5367 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305368}
5369
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305370static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5371 struct wireless_dev *wdev,
5372 const void *data,
5373 int data_len)
5374{
5375 int ret = 0;
5376
5377 vos_ssr_protect(__func__);
5378 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5379 vos_ssr_unprotect(__func__);
5380
5381 return ret;
5382}
5383
5384static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305385 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305386 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305387 int data_len)
5388{
5389 u8 peer[6] = {0};
5390 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305391 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5392 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5393 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305394 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305395 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305396
5397 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305398
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305399 if (!dev) {
5400 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5401 return -EINVAL;
5402 }
5403
5404 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5405 if (!pAdapter) {
5406 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5407 return -EINVAL;
5408 }
5409
Atul Mittal115287b2014-07-08 13:26:33 +05305410 status = wlan_hdd_validate_context(pHddCtx);
5411 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305412 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305413 return -EINVAL;
5414 }
5415 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305416 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305417 return -ENOTSUPP;
5418 }
5419 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5420 data, data_len,
5421 wlan_hdd_tdls_config_disable_policy)) {
5422 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5423 return -EINVAL;
5424 }
5425 /* Parse and fetch mac address */
5426 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5427 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5428 return -EINVAL;
5429 }
5430
5431 memcpy(peer, nla_data(
5432 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5433 sizeof(peer));
5434 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5435
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305436 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5437
5438 EXIT();
5439 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305440}
5441
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305442static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5443 struct wireless_dev *wdev,
5444 const void *data,
5445 int data_len)
5446{
5447 int ret = 0;
5448
5449 vos_ssr_protect(__func__);
5450 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5451 vos_ssr_unprotect(__func__);
5452
5453 return ret;
5454}
5455
Dasari Srinivas7875a302014-09-26 17:50:57 +05305456static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305457__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305458 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305459 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305460{
5461 struct net_device *dev = wdev->netdev;
5462 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5463 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5464 struct sk_buff *skb = NULL;
5465 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305466 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305467
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305468 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305469
5470 ret = wlan_hdd_validate_context(pHddCtx);
5471 if (0 != ret)
5472 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305473 return ret;
5474 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305475 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5476 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5477 fset |= WIFI_FEATURE_INFRA;
5478 }
5479
5480 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5481 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5482 fset |= WIFI_FEATURE_INFRA_5G;
5483 }
5484
5485#ifdef WLAN_FEATURE_P2P
5486 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5487 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5488 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5489 fset |= WIFI_FEATURE_P2P;
5490 }
5491#endif
5492
5493 /* Soft-AP is supported currently by default */
5494 fset |= WIFI_FEATURE_SOFT_AP;
5495
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305496 /* HOTSPOT is a supplicant feature, enable it by default */
5497 fset |= WIFI_FEATURE_HOTSPOT;
5498
Dasari Srinivas7875a302014-09-26 17:50:57 +05305499#ifdef WLAN_FEATURE_EXTSCAN
5500 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
5501 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
5502 hddLog(LOG1, FL("EXTScan is supported by firmware"));
5503 fset |= WIFI_FEATURE_EXTSCAN;
5504 }
5505#endif
5506
Dasari Srinivas7875a302014-09-26 17:50:57 +05305507 if (sme_IsFeatureSupportedByFW(NAN)) {
5508 hddLog(LOG1, FL("NAN is supported by firmware"));
5509 fset |= WIFI_FEATURE_NAN;
5510 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305511
5512 /* D2D RTT is not supported currently by default */
5513 if (sme_IsFeatureSupportedByFW(RTT)) {
5514 hddLog(LOG1, FL("RTT is supported by firmware"));
5515 fset |= WIFI_FEATURE_D2AP_RTT;
5516 }
5517
5518#ifdef FEATURE_WLAN_BATCH_SCAN
5519 if (fset & WIFI_FEATURE_EXTSCAN) {
5520 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5521 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5522 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5523 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5524 fset |= WIFI_FEATURE_BATCH_SCAN;
5525 }
5526#endif
5527
5528#ifdef FEATURE_WLAN_SCAN_PNO
5529 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5530 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5531 hddLog(LOG1, FL("PNO is supported by firmware"));
5532 fset |= WIFI_FEATURE_PNO;
5533 }
5534#endif
5535
5536 /* STA+STA is supported currently by default */
5537 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5538
5539#ifdef FEATURE_WLAN_TDLS
5540 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5541 sme_IsFeatureSupportedByFW(TDLS)) {
5542 hddLog(LOG1, FL("TDLS is supported by firmware"));
5543 fset |= WIFI_FEATURE_TDLS;
5544 }
5545
5546 /* TDLS_OFFCHANNEL is not supported currently by default */
5547#endif
5548
5549#ifdef WLAN_AP_STA_CONCURRENCY
5550 /* AP+STA concurrency is supported currently by default */
5551 fset |= WIFI_FEATURE_AP_STA;
5552#endif
5553
Mukul Sharma5add0532015-08-17 15:57:47 +05305554#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5555 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5556 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5557#endif
5558
Dasari Srinivas7875a302014-09-26 17:50:57 +05305559 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5560 NLMSG_HDRLEN);
5561
5562 if (!skb) {
5563 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5564 return -EINVAL;
5565 }
5566 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5567
5568 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5569 hddLog(LOGE, FL("nla put fail"));
5570 goto nla_put_failure;
5571 }
5572
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305573 ret = cfg80211_vendor_cmd_reply(skb);
5574 EXIT();
5575 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305576
5577nla_put_failure:
5578 kfree_skb(skb);
5579 return -EINVAL;
5580}
5581
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305582static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305583wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5584 struct wireless_dev *wdev,
5585 const void *data, int data_len)
5586{
5587 int ret = 0;
5588
5589 vos_ssr_protect(__func__);
5590 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5591 vos_ssr_unprotect(__func__);
5592
5593 return ret;
5594}
5595
5596static int
5597__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305598 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305599 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305600{
5601 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5602 uint8_t i, feature_sets, max_feature_sets;
5603 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5604 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305605 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5606 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305607
5608 ENTER();
5609
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305610 ret = wlan_hdd_validate_context(pHddCtx);
5611 if (0 != ret)
5612 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305613 return ret;
5614 }
5615
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305616 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5617 data, data_len, NULL)) {
5618 hddLog(LOGE, FL("Invalid ATTR"));
5619 return -EINVAL;
5620 }
5621
5622 /* Parse and fetch max feature set */
5623 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5624 hddLog(LOGE, FL("Attr max feature set size failed"));
5625 return -EINVAL;
5626 }
5627 max_feature_sets = nla_get_u32(
5628 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5629 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5630
5631 /* Fill feature combination matrix */
5632 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305633 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5634 WIFI_FEATURE_P2P;
5635
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305636 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5637 WIFI_FEATURE_SOFT_AP;
5638
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305639 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5640 WIFI_FEATURE_SOFT_AP;
5641
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305642 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5643 WIFI_FEATURE_SOFT_AP |
5644 WIFI_FEATURE_P2P;
5645
5646 /* Add more feature combinations here */
5647
5648 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5649 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5650 hddLog(LOG1, "Feature set matrix");
5651 for (i = 0; i < feature_sets; i++)
5652 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5653
5654 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5655 sizeof(u32) * feature_sets +
5656 NLMSG_HDRLEN);
5657
5658 if (reply_skb) {
5659 if (nla_put_u32(reply_skb,
5660 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5661 feature_sets) ||
5662 nla_put(reply_skb,
5663 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5664 sizeof(u32) * feature_sets, feature_set_matrix)) {
5665 hddLog(LOGE, FL("nla put fail"));
5666 kfree_skb(reply_skb);
5667 return -EINVAL;
5668 }
5669
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305670 ret = cfg80211_vendor_cmd_reply(reply_skb);
5671 EXIT();
5672 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305673 }
5674 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5675 return -ENOMEM;
5676
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305677}
5678
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305679static int
5680wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5681 struct wireless_dev *wdev,
5682 const void *data, int data_len)
5683{
5684 int ret = 0;
5685
5686 vos_ssr_protect(__func__);
5687 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5688 data_len);
5689 vos_ssr_unprotect(__func__);
5690
5691 return ret;
5692}
5693
Agarwal Ashish738843c2014-09-25 12:27:56 +05305694static const struct nla_policy
5695wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5696 +1] =
5697{
5698 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5699};
5700
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305701static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305702 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305703 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305704 int data_len)
5705{
5706 struct net_device *dev = wdev->netdev;
5707 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5708 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5709 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5710 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5711 eHalStatus status;
5712 u32 dfsFlag = 0;
5713
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305714 ENTER();
5715
Agarwal Ashish738843c2014-09-25 12:27:56 +05305716 status = wlan_hdd_validate_context(pHddCtx);
5717 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305718 return -EINVAL;
5719 }
5720 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5721 data, data_len,
5722 wlan_hdd_set_no_dfs_flag_config_policy)) {
5723 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5724 return -EINVAL;
5725 }
5726
5727 /* Parse and fetch required bandwidth kbps */
5728 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5729 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5730 return -EINVAL;
5731 }
5732
5733 dfsFlag = nla_get_u32(
5734 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5735 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5736 dfsFlag);
5737
5738 pHddCtx->disable_dfs_flag = dfsFlag;
5739
5740 sme_disable_dfs_channel(hHal, dfsFlag);
5741 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305742
5743 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305744 return 0;
5745}
Atul Mittal115287b2014-07-08 13:26:33 +05305746
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305747static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5748 struct wireless_dev *wdev,
5749 const void *data,
5750 int data_len)
5751{
5752 int ret = 0;
5753
5754 vos_ssr_protect(__func__);
5755 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5756 vos_ssr_unprotect(__func__);
5757
5758 return ret;
5759
5760}
5761
Mukul Sharma2a271632014-10-13 14:59:01 +05305762const struct
5763nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5764{
5765 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5766 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5767};
5768
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305769static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305770 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305771{
5772
5773 u8 bssid[6] = {0};
5774 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5775 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5776 eHalStatus status = eHAL_STATUS_SUCCESS;
5777 v_U32_t isFwrRoamEnabled = FALSE;
5778 int ret;
5779
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305780 ENTER();
5781
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305782 ret = wlan_hdd_validate_context(pHddCtx);
5783 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305784 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305785 }
5786
5787 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5788 data, data_len,
5789 qca_wlan_vendor_attr);
5790 if (ret){
5791 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5792 return -EINVAL;
5793 }
5794
5795 /* Parse and fetch Enable flag */
5796 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5798 return -EINVAL;
5799 }
5800
5801 isFwrRoamEnabled = nla_get_u32(
5802 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5803
5804 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5805
5806 /* Parse and fetch bssid */
5807 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5808 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5809 return -EINVAL;
5810 }
5811
5812 memcpy(bssid, nla_data(
5813 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5814 sizeof(bssid));
5815 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5816
5817 //Update roaming
5818 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305819 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305820 return status;
5821}
5822
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305823static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5824 struct wireless_dev *wdev, const void *data, int data_len)
5825{
5826 int ret = 0;
5827
5828 vos_ssr_protect(__func__);
5829 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5830 vos_ssr_unprotect(__func__);
5831
5832 return ret;
5833}
5834
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305835/**
5836 * __wlan_hdd_cfg80211_setband() - set band
5837 * @wiphy: Pointer to wireless phy
5838 * @wdev: Pointer to wireless device
5839 * @data: Pointer to data
5840 * @data_len: Data length
5841 *
5842 * Return: 0 on success, negative errno on failure
5843 */
5844static int
5845__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5846 struct wireless_dev *wdev,
5847 const void *data,
5848 int data_len)
5849{
5850 struct net_device *dev = wdev->netdev;
5851 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5852 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5853 int ret;
5854 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
5855 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
5856
5857 ENTER();
5858
5859 ret = wlan_hdd_validate_context(hdd_ctx);
5860 if (0 != ret) {
5861 hddLog(LOGE, FL("HDD context is not valid"));
5862 return ret;
5863 }
5864
5865 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
5866 policy)) {
5867 hddLog(LOGE, FL("Invalid ATTR"));
5868 return -EINVAL;
5869 }
5870
5871 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
5872 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
5873 return -EINVAL;
5874 }
5875
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305876 hdd_ctx->isSetBandByNL = TRUE;
5877 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305878 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305879 hdd_ctx->isSetBandByNL = FALSE;
5880
5881 EXIT();
5882 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305883}
5884
5885/**
5886 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
5887 * @wiphy: wiphy structure pointer
5888 * @wdev: Wireless device structure pointer
5889 * @data: Pointer to the data received
5890 * @data_len: Length of @data
5891 *
5892 * Return: 0 on success; errno on failure
5893 */
5894static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5895 struct wireless_dev *wdev,
5896 const void *data,
5897 int data_len)
5898{
5899 int ret = 0;
5900
5901 vos_ssr_protect(__func__);
5902 ret = __wlan_hdd_cfg80211_setband(wiphy,
5903 wdev, data, data_len);
5904 vos_ssr_unprotect(__func__);
5905
5906 return ret;
5907}
5908
Sunil Duttc69bccb2014-05-26 21:30:20 +05305909const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
5910{
Mukul Sharma2a271632014-10-13 14:59:01 +05305911 {
5912 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5913 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
5914 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5915 WIPHY_VENDOR_CMD_NEED_NETDEV |
5916 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305917 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05305918 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305919
5920 {
5921 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5922 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
5923 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5924 WIPHY_VENDOR_CMD_NEED_NETDEV |
5925 WIPHY_VENDOR_CMD_NEED_RUNNING,
5926 .doit = wlan_hdd_cfg80211_nan_request
5927 },
5928
Sunil Duttc69bccb2014-05-26 21:30:20 +05305929#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5930 {
5931 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5932 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
5933 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5934 WIPHY_VENDOR_CMD_NEED_NETDEV |
5935 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305936 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05305937 },
5938
5939 {
5940 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5941 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
5942 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5943 WIPHY_VENDOR_CMD_NEED_NETDEV |
5944 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305945 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05305946 },
5947
5948 {
5949 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5950 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
5951 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5952 WIPHY_VENDOR_CMD_NEED_NETDEV |
5953 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305954 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05305955 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305956#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305957#ifdef WLAN_FEATURE_EXTSCAN
5958 {
5959 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5960 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
5961 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5962 WIPHY_VENDOR_CMD_NEED_NETDEV |
5963 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305964 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05305965 },
5966 {
5967 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5968 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
5969 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5970 WIPHY_VENDOR_CMD_NEED_NETDEV |
5971 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305972 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05305973 },
5974 {
5975 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5976 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
5977 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5978 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305979 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05305980 },
5981 {
5982 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5983 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
5984 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5985 WIPHY_VENDOR_CMD_NEED_NETDEV |
5986 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305987 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05305988 },
5989 {
5990 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5991 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
5992 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5993 WIPHY_VENDOR_CMD_NEED_NETDEV |
5994 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305995 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05305996 },
5997 {
5998 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5999 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
6000 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6001 WIPHY_VENDOR_CMD_NEED_NETDEV |
6002 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306003 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05306004 },
6005 {
6006 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6007 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
6008 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6009 WIPHY_VENDOR_CMD_NEED_NETDEV |
6010 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306011 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05306012 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05306013 {
6014 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6015 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
6016 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6017 WIPHY_VENDOR_CMD_NEED_NETDEV |
6018 WIPHY_VENDOR_CMD_NEED_RUNNING,
6019 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
6020 },
6021 {
6022 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6023 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
6024 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6025 WIPHY_VENDOR_CMD_NEED_NETDEV |
6026 WIPHY_VENDOR_CMD_NEED_RUNNING,
6027 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
6028 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05306029#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05306030/*EXT TDLS*/
6031 {
6032 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6033 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
6034 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6035 WIPHY_VENDOR_CMD_NEED_NETDEV |
6036 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306037 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05306038 },
6039 {
6040 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6041 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
6042 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6043 WIPHY_VENDOR_CMD_NEED_NETDEV |
6044 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306045 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05306046 },
6047 {
6048 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6049 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
6050 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6051 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306052 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05306053 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05306054 {
6055 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6056 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
6057 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6058 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306059 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05306060 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05306061 {
6062 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6063 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
6064 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6065 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306066 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05306067 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05306068 {
6069 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6070 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
6071 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6072 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306073 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05306074 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306075 {
6076 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6077 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
6078 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6079 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306080 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306081 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306082 {
6083 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6084 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
6085 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6086 WIPHY_VENDOR_CMD_NEED_NETDEV |
6087 WIPHY_VENDOR_CMD_NEED_RUNNING,
6088 .doit = wlan_hdd_cfg80211_setband
6089 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05306090};
6091
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006092/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05306093static const
6094struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006095{
6096#ifdef FEATURE_WLAN_CH_AVOID
6097 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05306098 .vendor_id = QCA_NL80211_VENDOR_ID,
6099 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006100 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05306101#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
6102#ifdef WLAN_FEATURE_LINK_LAYER_STATS
6103 {
6104 /* Index = 1*/
6105 .vendor_id = QCA_NL80211_VENDOR_ID,
6106 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
6107 },
6108 {
6109 /* Index = 2*/
6110 .vendor_id = QCA_NL80211_VENDOR_ID,
6111 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
6112 },
6113 {
6114 /* Index = 3*/
6115 .vendor_id = QCA_NL80211_VENDOR_ID,
6116 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
6117 },
6118 {
6119 /* Index = 4*/
6120 .vendor_id = QCA_NL80211_VENDOR_ID,
6121 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
6122 },
6123 {
6124 /* Index = 5*/
6125 .vendor_id = QCA_NL80211_VENDOR_ID,
6126 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
6127 },
6128 {
6129 /* Index = 6*/
6130 .vendor_id = QCA_NL80211_VENDOR_ID,
6131 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
6132 },
6133#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05306134#ifdef WLAN_FEATURE_EXTSCAN
6135 {
6136 .vendor_id = QCA_NL80211_VENDOR_ID,
6137 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
6138 },
6139 {
6140 .vendor_id = QCA_NL80211_VENDOR_ID,
6141 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
6142 },
6143 {
6144 .vendor_id = QCA_NL80211_VENDOR_ID,
6145 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
6146 },
6147 {
6148 .vendor_id = QCA_NL80211_VENDOR_ID,
6149 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
6150 },
6151 {
6152 .vendor_id = QCA_NL80211_VENDOR_ID,
6153 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
6154 },
6155 {
6156 .vendor_id = QCA_NL80211_VENDOR_ID,
6157 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
6158 },
6159 {
6160 .vendor_id = QCA_NL80211_VENDOR_ID,
6161 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
6162 },
6163 {
6164 .vendor_id = QCA_NL80211_VENDOR_ID,
6165 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
6166 },
6167 {
6168 .vendor_id = QCA_NL80211_VENDOR_ID,
6169 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
6170 },
6171 {
6172 .vendor_id = QCA_NL80211_VENDOR_ID,
6173 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
6174 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05306175 {
6176 .vendor_id = QCA_NL80211_VENDOR_ID,
6177 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
6178 },
6179 {
6180 .vendor_id = QCA_NL80211_VENDOR_ID,
6181 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
6182 },
6183 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
6184 .vendor_id = QCA_NL80211_VENDOR_ID,
6185 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
6186 },
6187 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
6188 .vendor_id = QCA_NL80211_VENDOR_ID,
6189 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
6190 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05306191#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05306192/*EXT TDLS*/
6193 {
6194 .vendor_id = QCA_NL80211_VENDOR_ID,
6195 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
6196 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05306197
6198 {
6199 .vendor_id = QCA_NL80211_VENDOR_ID,
6200 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
6201 },
6202
Sushant Kaushik084f6592015-09-10 13:11:56 +05306203 {
6204 .vendor_id = QCA_NL80211_VENDOR_ID,
6205 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
6206 }
6207
6208
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006209};
6210
Jeff Johnson295189b2012-06-20 16:38:30 -07006211/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306212 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306213 * This function is called by hdd_wlan_startup()
6214 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306215 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07006216 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306217struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07006218{
6219 struct wiphy *wiphy;
6220 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306221 /*
6222 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07006223 */
6224 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
6225
6226 if (!wiphy)
6227 {
6228 /* Print error and jump into err label and free the memory */
6229 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
6230 return NULL;
6231 }
6232
Sunil Duttc69bccb2014-05-26 21:30:20 +05306233
Jeff Johnson295189b2012-06-20 16:38:30 -07006234 return wiphy;
6235}
6236
6237/*
6238 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306239 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07006240 * private ioctl to change the band value
6241 */
6242int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
6243{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306244 int i, j;
6245 eNVChannelEnabledType channelEnabledState;
6246
Jeff Johnsone7245742012-09-05 17:12:55 -07006247 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306248
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306249 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006250 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306251
6252 if (NULL == wiphy->bands[i])
6253 {
6254 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
6255 __func__, i);
6256 continue;
6257 }
6258
6259 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6260 {
6261 struct ieee80211_supported_band *band = wiphy->bands[i];
6262
6263 channelEnabledState = vos_nv_getChannelEnabledState(
6264 band->channels[j].hw_value);
6265
6266 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
6267 {
Abhishek Singh678227a2014-11-04 10:52:38 +05306268 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306269 continue;
6270 }
6271 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
6272 {
6273 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6274 continue;
6275 }
6276
6277 if (NV_CHANNEL_DISABLE == channelEnabledState ||
6278 NV_CHANNEL_INVALID == channelEnabledState)
6279 {
6280 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6281 }
6282 else if (NV_CHANNEL_DFS == channelEnabledState)
6283 {
6284 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6285 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
6286 }
6287 else
6288 {
6289 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
6290 |IEEE80211_CHAN_RADAR);
6291 }
6292 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006293 }
6294 return 0;
6295}
6296/*
6297 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306298 * This function is called by hdd_wlan_startup()
6299 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07006300 * This function is used to initialize and register wiphy structure.
6301 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306302int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006303 struct wiphy *wiphy,
6304 hdd_config_t *pCfg
6305 )
6306{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306307 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05306308 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6309
Jeff Johnsone7245742012-09-05 17:12:55 -07006310 ENTER();
6311
Jeff Johnson295189b2012-06-20 16:38:30 -07006312 /* Now bind the underlying wlan device with wiphy */
6313 set_wiphy_dev(wiphy, dev);
6314
6315 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07006316
Kiet Lam6c583332013-10-14 05:37:09 +05306317#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07006318 /* the flag for the other case would be initialzed in
6319 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07006320 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05306321#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07006322
Amar Singhalfddc28c2013-09-05 13:03:40 -07006323 /* This will disable updating of NL channels from passive to
6324 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306325#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6326 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
6327#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07006328 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306329#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07006330
Amar Singhala49cbc52013-10-08 18:37:44 -07006331
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006332#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07006333 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
6334 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
6335 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07006336 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306337#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6338 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
6339#else
6340 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
6341#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006342#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07006343
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006344#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006345 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08006346#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006347 || pCfg->isFastRoamIniFeatureEnabled
6348#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006349#ifdef FEATURE_WLAN_ESE
6350 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006351#endif
6352 )
6353 {
6354 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
6355 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08006356#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006357#ifdef FEATURE_WLAN_TDLS
6358 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
6359 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
6360#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306361#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05306362 if (pCfg->configPNOScanSupport)
6363 {
6364 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
6365 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
6366 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
6367 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
6368 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306369#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006370
Abhishek Singh10d85972015-04-17 10:27:23 +05306371#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6372 wiphy->features |= NL80211_FEATURE_HT_IBSS;
6373#endif
6374
Amar Singhalfddc28c2013-09-05 13:03:40 -07006375#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006376 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
6377 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07006378 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006379 driver need to determine what to do with both
6380 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07006381
6382 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07006383#else
6384 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07006385#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006386
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306387 wiphy->max_scan_ssids = MAX_SCAN_SSID;
6388
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05306389 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07006390
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306391 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
6392
Jeff Johnson295189b2012-06-20 16:38:30 -07006393 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05306394 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
6395 | BIT(NL80211_IFTYPE_ADHOC)
6396 | BIT(NL80211_IFTYPE_P2P_CLIENT)
6397 | BIT(NL80211_IFTYPE_P2P_GO)
6398 | BIT(NL80211_IFTYPE_AP);
6399
6400 if (VOS_MONITOR_MODE == hdd_get_conparam())
6401 {
6402 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
6403 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006404
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306405 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006406 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306407#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6408 if( pCfg->enableMCC )
6409 {
6410 /* Currently, supports up to two channels */
6411 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006412
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306413 if( !pCfg->allowMCCGODiffBI )
6414 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006415
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306416 }
6417 wiphy->iface_combinations = &wlan_hdd_iface_combination;
6418 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006419#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306420 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006421
Jeff Johnson295189b2012-06-20 16:38:30 -07006422 /* Before registering we need to update the ht capabilitied based
6423 * on ini values*/
6424 if( !pCfg->ShortGI20MhzEnable )
6425 {
6426 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6427 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6428 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6429 }
6430
6431 if( !pCfg->ShortGI40MhzEnable )
6432 {
6433 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
6434 }
6435
6436 if( !pCfg->nChannelBondingMode5GHz )
6437 {
6438 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6439 }
6440
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306441 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05306442 if (true == hdd_is_5g_supported(pHddCtx))
6443 {
6444 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
6445 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306446
6447 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
6448 {
6449
6450 if (NULL == wiphy->bands[i])
6451 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05306452 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306453 __func__, i);
6454 continue;
6455 }
6456
6457 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6458 {
6459 struct ieee80211_supported_band *band = wiphy->bands[i];
6460
6461 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
6462 {
6463 // Enable social channels for P2P
6464 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
6465 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6466 else
6467 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6468 continue;
6469 }
6470 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
6471 {
6472 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6473 continue;
6474 }
6475 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006476 }
6477 /*Initialise the supported cipher suite details*/
6478 wiphy->cipher_suites = hdd_cipher_suites;
6479 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
6480
6481 /*signal strength in mBm (100*dBm) */
6482 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
6483
6484#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05306485 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07006486#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006487
Sunil Duttc69bccb2014-05-26 21:30:20 +05306488 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
6489 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006490 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
6491 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
6492
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306493 EXIT();
6494 return 0;
6495}
6496
6497/* In this function we are registering wiphy. */
6498int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
6499{
6500 ENTER();
6501 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006502 if (0 > wiphy_register(wiphy))
6503 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306504 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07006505 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
6506 return -EIO;
6507 }
6508
6509 EXIT();
6510 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306511}
Jeff Johnson295189b2012-06-20 16:38:30 -07006512
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306513/* In this function we are updating channel list when,
6514 regulatory domain is FCC and country code is US.
6515 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
6516 As per FCC smart phone is not a indoor device.
6517 GO should not opeate on indoor channels */
6518void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
6519{
6520 int j;
6521 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6522 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
6523 //Default counrtycode from NV at the time of wiphy initialization.
6524 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
6525 &defaultCountryCode[0]))
6526 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006527 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306528 }
6529 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
6530 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306531 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
6532 {
6533 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
6534 return;
6535 }
6536 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
6537 {
6538 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
6539 // Mark UNII -1 band channel as passive
6540 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
6541 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
6542 }
6543 }
6544}
6545
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306546/* This function registers for all frame which supplicant is interested in */
6547void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006548{
Jeff Johnson295189b2012-06-20 16:38:30 -07006549 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6550 /* Register for all P2P action, public action etc frames */
6551 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6552
Jeff Johnsone7245742012-09-05 17:12:55 -07006553 ENTER();
6554
Jeff Johnson295189b2012-06-20 16:38:30 -07006555 /* Right now we are registering these frame when driver is getting
6556 initialized. Once we will move to 2.6.37 kernel, in which we have
6557 frame register ops, we will move this code as a part of that */
6558 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306559 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006560 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6561
6562 /* GAS Initial Response */
6563 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6564 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306565
Jeff Johnson295189b2012-06-20 16:38:30 -07006566 /* GAS Comeback Request */
6567 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6568 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6569
6570 /* GAS Comeback Response */
6571 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6572 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6573
6574 /* P2P Public Action */
6575 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306576 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006577 P2P_PUBLIC_ACTION_FRAME_SIZE );
6578
6579 /* P2P Action */
6580 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6581 (v_U8_t*)P2P_ACTION_FRAME,
6582 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07006583
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05306584 /* WNM BSS Transition Request frame */
6585 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6586 (v_U8_t*)WNM_BSS_ACTION_FRAME,
6587 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006588
6589 /* WNM-Notification */
6590 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6591 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6592 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006593}
6594
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306595void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006596{
Jeff Johnson295189b2012-06-20 16:38:30 -07006597 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6598 /* Register for all P2P action, public action etc frames */
6599 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6600
Jeff Johnsone7245742012-09-05 17:12:55 -07006601 ENTER();
6602
Jeff Johnson295189b2012-06-20 16:38:30 -07006603 /* Right now we are registering these frame when driver is getting
6604 initialized. Once we will move to 2.6.37 kernel, in which we have
6605 frame register ops, we will move this code as a part of that */
6606 /* GAS Initial Request */
6607
6608 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6609 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6610
6611 /* GAS Initial Response */
6612 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6613 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306614
Jeff Johnson295189b2012-06-20 16:38:30 -07006615 /* GAS Comeback Request */
6616 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6617 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6618
6619 /* GAS Comeback Response */
6620 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6621 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6622
6623 /* P2P Public Action */
6624 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306625 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006626 P2P_PUBLIC_ACTION_FRAME_SIZE );
6627
6628 /* P2P Action */
6629 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6630 (v_U8_t*)P2P_ACTION_FRAME,
6631 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006632 /* WNM-Notification */
6633 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6634 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6635 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006636}
6637
6638#ifdef FEATURE_WLAN_WAPI
6639void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05306640 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006641{
6642 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6643 tCsrRoamSetKey setKey;
6644 v_BOOL_t isConnected = TRUE;
6645 int status = 0;
6646 v_U32_t roamId= 0xFF;
6647 tANI_U8 *pKeyPtr = NULL;
6648 int n = 0;
6649
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306650 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6651 __func__, hdd_device_modetoString(pAdapter->device_mode),
6652 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006653
Gopichand Nakkalae7480202013-02-11 15:24:22 +05306654 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006655 setKey.keyId = key_index; // Store Key ID
6656 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
6657 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
6658 setKey.paeRole = 0 ; // the PAE role
6659 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
6660 {
6661 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
6662 }
6663 else
6664 {
6665 isConnected = hdd_connIsConnected(pHddStaCtx);
6666 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
6667 }
6668 setKey.keyLength = key_Len;
6669 pKeyPtr = setKey.Key;
6670 memcpy( pKeyPtr, key, key_Len);
6671
Arif Hussain6d2a3322013-11-17 19:50:10 -08006672 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07006673 __func__, key_Len);
6674 for (n = 0 ; n < key_Len; n++)
6675 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
6676 __func__,n,setKey.Key[n]);
6677
6678 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
6679 if ( isConnected )
6680 {
6681 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
6682 pAdapter->sessionId, &setKey, &roamId );
6683 }
6684 if ( status != 0 )
6685 {
6686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6687 "[%4d] sme_RoamSetKey returned ERROR status= %d",
6688 __LINE__, status );
6689 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
6690 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05306691 /* Need to clear any trace of key value in the memory.
6692 * Thus zero out the memory even though it is local
6693 * variable.
6694 */
6695 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006696}
6697#endif /* FEATURE_WLAN_WAPI*/
6698
6699#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306700int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006701 beacon_data_t **ppBeacon,
6702 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006703#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306704int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006705 beacon_data_t **ppBeacon,
6706 struct cfg80211_beacon_data *params,
6707 int dtim_period)
6708#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306709{
Jeff Johnson295189b2012-06-20 16:38:30 -07006710 int size;
6711 beacon_data_t *beacon = NULL;
6712 beacon_data_t *old = NULL;
6713 int head_len,tail_len;
6714
Jeff Johnsone7245742012-09-05 17:12:55 -07006715 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006716 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306717 {
6718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6719 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006720 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306721 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006722
6723 old = pAdapter->sessionCtx.ap.beacon;
6724
6725 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306726 {
6727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6728 FL("session(%d) old and new heads points to NULL"),
6729 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006730 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306731 }
6732
6733 if (params->tail && !params->tail_len)
6734 {
6735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6736 FL("tail_len is zero but tail is not NULL"));
6737 return -EINVAL;
6738 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006739
Jeff Johnson295189b2012-06-20 16:38:30 -07006740#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
6741 /* Kernel 3.0 is not updating dtim_period for set beacon */
6742 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306743 {
6744 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6745 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006746 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306747 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006748#endif
6749
6750 if(params->head)
6751 head_len = params->head_len;
6752 else
6753 head_len = old->head_len;
6754
6755 if(params->tail || !old)
6756 tail_len = params->tail_len;
6757 else
6758 tail_len = old->tail_len;
6759
6760 size = sizeof(beacon_data_t) + head_len + tail_len;
6761
6762 beacon = kzalloc(size, GFP_KERNEL);
6763
6764 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306765 {
6766 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6767 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006768 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306769 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006770
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006771#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006772 if(params->dtim_period || !old )
6773 beacon->dtim_period = params->dtim_period;
6774 else
6775 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006776#else
6777 if(dtim_period || !old )
6778 beacon->dtim_period = dtim_period;
6779 else
6780 beacon->dtim_period = old->dtim_period;
6781#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306782
Jeff Johnson295189b2012-06-20 16:38:30 -07006783 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6784 beacon->tail = beacon->head + head_len;
6785 beacon->head_len = head_len;
6786 beacon->tail_len = tail_len;
6787
6788 if(params->head) {
6789 memcpy (beacon->head,params->head,beacon->head_len);
6790 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306791 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006792 if(old)
6793 memcpy (beacon->head,old->head,beacon->head_len);
6794 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306795
Jeff Johnson295189b2012-06-20 16:38:30 -07006796 if(params->tail) {
6797 memcpy (beacon->tail,params->tail,beacon->tail_len);
6798 }
6799 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306800 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006801 memcpy (beacon->tail,old->tail,beacon->tail_len);
6802 }
6803
6804 *ppBeacon = beacon;
6805
6806 kfree(old);
6807
6808 return 0;
6809
6810}
Jeff Johnson295189b2012-06-20 16:38:30 -07006811
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306812v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
6813#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6814 const v_U8_t *pIes,
6815#else
6816 v_U8_t *pIes,
6817#endif
6818 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006819{
6820 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306821 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07006822 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306823
Jeff Johnson295189b2012-06-20 16:38:30 -07006824 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306825 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006826 elem_id = ptr[0];
6827 elem_len = ptr[1];
6828 left -= 2;
6829 if(elem_len > left)
6830 {
6831 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006832 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006833 eid,elem_len,left);
6834 return NULL;
6835 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306836 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006837 {
6838 return ptr;
6839 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306840
Jeff Johnson295189b2012-06-20 16:38:30 -07006841 left -= elem_len;
6842 ptr += (elem_len + 2);
6843 }
6844 return NULL;
6845}
6846
Jeff Johnson295189b2012-06-20 16:38:30 -07006847/* Check if rate is 11g rate or not */
6848static int wlan_hdd_rate_is_11g(u8 rate)
6849{
Sanjay Devnani28322e22013-06-21 16:13:40 -07006850 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006851 u8 i;
6852 for (i = 0; i < 8; i++)
6853 {
6854 if(rate == gRateArray[i])
6855 return TRUE;
6856 }
6857 return FALSE;
6858}
6859
6860/* Check for 11g rate and set proper 11g only mode */
6861static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
6862 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
6863{
6864 u8 i, num_rates = pIe[0];
6865
6866 pIe += 1;
6867 for ( i = 0; i < num_rates; i++)
6868 {
6869 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
6870 {
6871 /* If rate set have 11g rate than change the mode to 11G */
6872 *pSapHw_mode = eSAP_DOT11_MODE_11g;
6873 if (pIe[i] & BASIC_RATE_MASK)
6874 {
6875 /* If we have 11g rate as basic rate, it means mode
6876 is 11g only mode.
6877 */
6878 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
6879 *pCheckRatesfor11g = FALSE;
6880 }
6881 }
6882 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6883 {
6884 *require_ht = TRUE;
6885 }
6886 }
6887 return;
6888}
6889
6890static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
6891{
6892 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6893 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6894 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6895 u8 checkRatesfor11g = TRUE;
6896 u8 require_ht = FALSE;
6897 u8 *pIe=NULL;
6898
6899 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
6900
6901 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6902 pBeacon->head_len, WLAN_EID_SUPP_RATES);
6903 if (pIe != NULL)
6904 {
6905 pIe += 1;
6906 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6907 &pConfig->SapHw_mode);
6908 }
6909
6910 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6911 WLAN_EID_EXT_SUPP_RATES);
6912 if (pIe != NULL)
6913 {
6914
6915 pIe += 1;
6916 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6917 &pConfig->SapHw_mode);
6918 }
6919
6920 if( pConfig->channel > 14 )
6921 {
6922 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
6923 }
6924
6925 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6926 WLAN_EID_HT_CAPABILITY);
6927
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306928 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006929 {
6930 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
6931 if(require_ht)
6932 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
6933 }
6934}
6935
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306936static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
6937 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
6938{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006939 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306940 v_U8_t *pIe = NULL;
6941 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6942
6943 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6944 pBeacon->tail, pBeacon->tail_len);
6945
6946 if (pIe)
6947 {
6948 ielen = pIe[1] + 2;
6949 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6950 {
6951 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
6952 }
6953 else
6954 {
6955 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
6956 return -EINVAL;
6957 }
6958 *total_ielen += ielen;
6959 }
6960 return 0;
6961}
6962
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006963static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
6964 v_U8_t *genie, v_U8_t *total_ielen)
6965{
6966 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6967 int left = pBeacon->tail_len;
6968 v_U8_t *ptr = pBeacon->tail;
6969 v_U8_t elem_id, elem_len;
6970 v_U16_t ielen = 0;
6971
6972 if ( NULL == ptr || 0 == left )
6973 return;
6974
6975 while (left >= 2)
6976 {
6977 elem_id = ptr[0];
6978 elem_len = ptr[1];
6979 left -= 2;
6980 if (elem_len > left)
6981 {
6982 hddLog( VOS_TRACE_LEVEL_ERROR,
6983 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
6984 elem_id, elem_len, left);
6985 return;
6986 }
6987 if (IE_EID_VENDOR == elem_id)
6988 {
6989 /* skipping the VSIE's which we don't want to include or
6990 * it will be included by existing code
6991 */
6992 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
6993#ifdef WLAN_FEATURE_WFD
6994 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
6995#endif
6996 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6997 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6998 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
6999 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7000 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
7001 {
7002 ielen = ptr[1] + 2;
7003 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
7004 {
7005 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
7006 *total_ielen += ielen;
7007 }
7008 else
7009 {
7010 hddLog( VOS_TRACE_LEVEL_ERROR,
7011 "IE Length is too big "
7012 "IEs eid=%d elem_len=%d total_ie_lent=%d",
7013 elem_id, elem_len, *total_ielen);
7014 }
7015 }
7016 }
7017
7018 left -= elem_len;
7019 ptr += (elem_len + 2);
7020 }
7021 return;
7022}
7023
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007024#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007025static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
7026 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007027#else
7028static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
7029 struct cfg80211_beacon_data *params)
7030#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007031{
7032 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307033 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007034 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07007035 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007036
7037 genie = vos_mem_malloc(MAX_GENIE_LEN);
7038
7039 if(genie == NULL) {
7040
7041 return -ENOMEM;
7042 }
7043
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307044 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7045 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007046 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307047 hddLog(LOGE,
7048 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307049 ret = -EINVAL;
7050 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007051 }
7052
7053#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307054 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7055 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
7056 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307057 hddLog(LOGE,
7058 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307059 ret = -EINVAL;
7060 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007061 }
7062#endif
7063
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307064 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7065 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007066 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307067 hddLog(LOGE,
7068 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307069 ret = -EINVAL;
7070 goto done;
7071 }
7072
7073 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
7074 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007075 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07007076 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007077
7078 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7079 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
7080 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
7081 {
7082 hddLog(LOGE,
7083 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007084 ret = -EINVAL;
7085 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007086 }
7087
7088 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7089 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
7090 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7091 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7092 ==eHAL_STATUS_FAILURE)
7093 {
7094 hddLog(LOGE,
7095 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007096 ret = -EINVAL;
7097 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007098 }
7099
7100 // Added for ProResp IE
7101 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
7102 {
7103 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
7104 u8 probe_rsp_ie_len[3] = {0};
7105 u8 counter = 0;
7106 /* Check Probe Resp Length if it is greater then 255 then Store
7107 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
7108 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
7109 Store More then 255 bytes into One Variable.
7110 */
7111 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
7112 {
7113 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
7114 {
7115 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
7116 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
7117 }
7118 else
7119 {
7120 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
7121 rem_probe_resp_ie_len = 0;
7122 }
7123 }
7124
7125 rem_probe_resp_ie_len = 0;
7126
7127 if (probe_rsp_ie_len[0] > 0)
7128 {
7129 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7130 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
7131 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7132 probe_rsp_ie_len[0], NULL,
7133 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7134 {
7135 hddLog(LOGE,
7136 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007137 ret = -EINVAL;
7138 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007139 }
7140 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
7141 }
7142
7143 if (probe_rsp_ie_len[1] > 0)
7144 {
7145 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7146 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
7147 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7148 probe_rsp_ie_len[1], NULL,
7149 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7150 {
7151 hddLog(LOGE,
7152 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007153 ret = -EINVAL;
7154 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007155 }
7156 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
7157 }
7158
7159 if (probe_rsp_ie_len[2] > 0)
7160 {
7161 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7162 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
7163 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7164 probe_rsp_ie_len[2], NULL,
7165 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7166 {
7167 hddLog(LOGE,
7168 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007169 ret = -EINVAL;
7170 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007171 }
7172 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
7173 }
7174
7175 if (probe_rsp_ie_len[1] == 0 )
7176 {
7177 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7178 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7179 eANI_BOOLEAN_FALSE) )
7180 {
7181 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007182 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007183 }
7184 }
7185
7186 if (probe_rsp_ie_len[2] == 0 )
7187 {
7188 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7189 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7190 eANI_BOOLEAN_FALSE) )
7191 {
7192 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007193 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007194 }
7195 }
7196
7197 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7198 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
7199 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7200 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7201 == eHAL_STATUS_FAILURE)
7202 {
7203 hddLog(LOGE,
7204 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007205 ret = -EINVAL;
7206 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007207 }
7208 }
7209 else
7210 {
7211 // Reset WNI_CFG_PROBE_RSP Flags
7212 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
7213
7214 hddLog(VOS_TRACE_LEVEL_INFO,
7215 "%s: No Probe Response IE received in set beacon",
7216 __func__);
7217 }
7218
7219 // Added for AssocResp IE
7220 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
7221 {
7222 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7223 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
7224 params->assocresp_ies_len, NULL,
7225 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7226 {
7227 hddLog(LOGE,
7228 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007229 ret = -EINVAL;
7230 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007231 }
7232
7233 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7234 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
7235 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7236 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7237 == eHAL_STATUS_FAILURE)
7238 {
7239 hddLog(LOGE,
7240 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007241 ret = -EINVAL;
7242 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007243 }
7244 }
7245 else
7246 {
7247 hddLog(VOS_TRACE_LEVEL_INFO,
7248 "%s: No Assoc Response IE received in set beacon",
7249 __func__);
7250
7251 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7252 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7253 eANI_BOOLEAN_FALSE) )
7254 {
7255 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007256 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007257 }
7258 }
7259
Jeff Johnsone7245742012-09-05 17:12:55 -07007260done:
Jeff Johnson295189b2012-06-20 16:38:30 -07007261 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307262 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007263}
Jeff Johnson295189b2012-06-20 16:38:30 -07007264
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307265/*
Jeff Johnson295189b2012-06-20 16:38:30 -07007266 * FUNCTION: wlan_hdd_validate_operation_channel
7267 * called by wlan_hdd_cfg80211_start_bss() and
7268 * wlan_hdd_cfg80211_set_channel()
7269 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307270 * channel list.
7271 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007272VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007273{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307274
Jeff Johnson295189b2012-06-20 16:38:30 -07007275 v_U32_t num_ch = 0;
7276 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7277 u32 indx = 0;
7278 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307279 v_U8_t fValidChannel = FALSE, count = 0;
7280 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307281
Jeff Johnson295189b2012-06-20 16:38:30 -07007282 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7283
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307284 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007285 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307286 /* Validate the channel */
7287 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007288 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307289 if ( channel == rfChannels[count].channelNum )
7290 {
7291 fValidChannel = TRUE;
7292 break;
7293 }
7294 }
7295 if (fValidChannel != TRUE)
7296 {
7297 hddLog(VOS_TRACE_LEVEL_ERROR,
7298 "%s: Invalid Channel [%d]", __func__, channel);
7299 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007300 }
7301 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307302 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007303 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307304 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7305 valid_ch, &num_ch))
7306 {
7307 hddLog(VOS_TRACE_LEVEL_ERROR,
7308 "%s: failed to get valid channel list", __func__);
7309 return VOS_STATUS_E_FAILURE;
7310 }
7311 for (indx = 0; indx < num_ch; indx++)
7312 {
7313 if (channel == valid_ch[indx])
7314 {
7315 break;
7316 }
7317 }
7318
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05307319 if (indx >= num_ch)
7320 {
7321 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
7322 {
7323 eCsrBand band;
7324 unsigned int freq;
7325
7326 sme_GetFreqBand(hHal, &band);
7327
7328 if (eCSR_BAND_5G == band)
7329 {
7330#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
7331 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
7332 {
7333 freq = ieee80211_channel_to_frequency(channel,
7334 IEEE80211_BAND_2GHZ);
7335 }
7336 else
7337 {
7338 freq = ieee80211_channel_to_frequency(channel,
7339 IEEE80211_BAND_5GHZ);
7340 }
7341#else
7342 freq = ieee80211_channel_to_frequency(channel);
7343#endif
7344 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
7345 return VOS_STATUS_SUCCESS;
7346 }
7347 }
7348
7349 hddLog(VOS_TRACE_LEVEL_ERROR,
7350 "%s: Invalid Channel [%d]", __func__, channel);
7351 return VOS_STATUS_E_FAILURE;
7352 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007353 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05307354
Jeff Johnson295189b2012-06-20 16:38:30 -07007355 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307356
Jeff Johnson295189b2012-06-20 16:38:30 -07007357}
7358
Viral Modi3a32cc52013-02-08 11:14:52 -08007359/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307360 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08007361 * This function is used to set the channel number
7362 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307363static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08007364 struct ieee80211_channel *chan,
7365 enum nl80211_channel_type channel_type
7366 )
7367{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307368 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08007369 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07007370 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08007371 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307372 hdd_context_t *pHddCtx;
7373 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007374
7375 ENTER();
7376
7377 if( NULL == dev )
7378 {
7379 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007380 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007381 return -ENODEV;
7382 }
7383 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307384
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307385 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7386 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
7387 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08007388 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307389 "%s: device_mode = %s (%d) freq = %d", __func__,
7390 hdd_device_modetoString(pAdapter->device_mode),
7391 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307392
7393 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7394 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307395 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08007396 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307397 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007398 }
7399
7400 /*
7401 * Do freq to chan conversion
7402 * TODO: for 11a
7403 */
7404
7405 channel = ieee80211_frequency_to_channel(freq);
7406
7407 /* Check freq range */
7408 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
7409 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
7410 {
7411 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007412 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08007413 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
7414 WNI_CFG_CURRENT_CHANNEL_STAMAX);
7415 return -EINVAL;
7416 }
7417
7418 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7419
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05307420 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
7421 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08007422 {
7423 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
7424 {
7425 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007426 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08007427 return -EINVAL;
7428 }
7429 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7430 "%s: set channel to [%d] for device mode =%d",
7431 __func__, channel,pAdapter->device_mode);
7432 }
7433 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08007434 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08007435 )
7436 {
7437 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7438 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
7439 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7440
7441 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
7442 {
7443 /* Link is up then return cant set channel*/
7444 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007445 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007446 return -EINVAL;
7447 }
7448
7449 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
7450 pHddStaCtx->conn_info.operationChannel = channel;
7451 pRoamProfile->ChannelInfo.ChannelList =
7452 &pHddStaCtx->conn_info.operationChannel;
7453 }
7454 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08007455 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08007456 )
7457 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307458 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
7459 {
7460 if(VOS_STATUS_SUCCESS !=
7461 wlan_hdd_validate_operation_channel(pAdapter,channel))
7462 {
7463 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007464 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307465 return -EINVAL;
7466 }
7467 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7468 }
7469 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08007470 {
7471 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
7472
7473 /* If auto channel selection is configured as enable/ 1 then ignore
7474 channel set by supplicant
7475 */
7476 if ( cfg_param->apAutoChannelSelection )
7477 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307478 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
7479 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08007480 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307481 "%s: set channel to auto channel (0) for device mode =%s (%d)",
7482 __func__, hdd_device_modetoString(pAdapter->device_mode),
7483 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08007484 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307485 else
7486 {
7487 if(VOS_STATUS_SUCCESS !=
7488 wlan_hdd_validate_operation_channel(pAdapter,channel))
7489 {
7490 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007491 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307492 return -EINVAL;
7493 }
7494 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7495 }
Viral Modi3a32cc52013-02-08 11:14:52 -08007496 }
7497 }
7498 else
7499 {
7500 hddLog(VOS_TRACE_LEVEL_FATAL,
7501 "%s: Invalid device mode failed to set valid channel", __func__);
7502 return -EINVAL;
7503 }
7504 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307505 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007506}
7507
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307508static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
7509 struct net_device *dev,
7510 struct ieee80211_channel *chan,
7511 enum nl80211_channel_type channel_type
7512 )
7513{
7514 int ret;
7515
7516 vos_ssr_protect(__func__);
7517 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
7518 vos_ssr_unprotect(__func__);
7519
7520 return ret;
7521}
7522
Jeff Johnson295189b2012-06-20 16:38:30 -07007523#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7524static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7525 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007526#else
7527static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7528 struct cfg80211_beacon_data *params,
7529 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307530 enum nl80211_hidden_ssid hidden_ssid,
7531 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007532#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007533{
7534 tsap_Config_t *pConfig;
7535 beacon_data_t *pBeacon = NULL;
7536 struct ieee80211_mgmt *pMgmt_frame;
7537 v_U8_t *pIe=NULL;
7538 v_U16_t capab_info;
7539 eCsrAuthType RSNAuthType;
7540 eCsrEncryptionType RSNEncryptType;
7541 eCsrEncryptionType mcRSNEncryptType;
7542 int status = VOS_STATUS_SUCCESS;
7543 tpWLAN_SAPEventCB pSapEventCallback;
7544 hdd_hostapd_state_t *pHostapdState;
7545 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
7546 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307547 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007548 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307549 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07007550 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08007551 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05307552 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07007553 v_BOOL_t MFPCapable = VOS_FALSE;
7554 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307555 v_BOOL_t sapEnable11AC =
7556 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07007557 ENTER();
7558
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307559 iniConfig = pHddCtx->cfg_ini;
7560
Jeff Johnson295189b2012-06-20 16:38:30 -07007561 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7562
7563 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7564
7565 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7566
7567 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7568
7569 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7570
7571 //channel is already set in the set_channel Call back
7572 //pConfig->channel = pCommitConfig->channel;
7573
7574 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307575 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07007576 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
7577
7578 pConfig->dtim_period = pBeacon->dtim_period;
7579
Arif Hussain6d2a3322013-11-17 19:50:10 -08007580 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07007581 pConfig->dtim_period);
7582
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08007583 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07007584 {
7585 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007586 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05307587 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
7588 {
7589 tANI_BOOLEAN restartNeeded;
7590 pConfig->ieee80211d = 1;
7591 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
7592 sme_setRegInfo(hHal, pConfig->countryCode);
7593 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
7594 }
7595 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007596 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07007597 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07007598 pConfig->ieee80211d = 1;
7599 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
7600 sme_setRegInfo(hHal, pConfig->countryCode);
7601 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07007602 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007603 else
7604 {
7605 pConfig->ieee80211d = 0;
7606 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307607 /*
7608 * If auto channel is configured i.e. channel is 0,
7609 * so skip channel validation.
7610 */
7611 if( AUTO_CHANNEL_SELECT != pConfig->channel )
7612 {
7613 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
7614 {
7615 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007616 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307617 return -EINVAL;
7618 }
7619 }
7620 else
7621 {
7622 if(1 != pHddCtx->is_dynamic_channel_range_set)
7623 {
7624 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
7625 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
7626 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
7627 }
7628 pHddCtx->is_dynamic_channel_range_set = 0;
7629 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007630 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007631 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007632 {
7633 pConfig->ieee80211d = 0;
7634 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307635
7636#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7637 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7638 pConfig->authType = eSAP_OPEN_SYSTEM;
7639 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7640 pConfig->authType = eSAP_SHARED_KEY;
7641 else
7642 pConfig->authType = eSAP_AUTO_SWITCH;
7643#else
7644 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7645 pConfig->authType = eSAP_OPEN_SYSTEM;
7646 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7647 pConfig->authType = eSAP_SHARED_KEY;
7648 else
7649 pConfig->authType = eSAP_AUTO_SWITCH;
7650#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007651
7652 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307653
7654 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07007655 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
7656
7657 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7658
7659 /*Set wps station to configured*/
7660 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7661
7662 if(pIe)
7663 {
7664 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
7665 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007666 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07007667 return -EINVAL;
7668 }
7669 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
7670 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007671 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07007672 /* Check 15 bit of WPS IE as it contain information for wps state
7673 * WPS state
7674 */
7675 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
7676 {
7677 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
7678 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
7679 {
7680 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7681 }
7682 }
7683 }
7684 else
7685 {
7686 pConfig->wps_state = SAP_WPS_DISABLED;
7687 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307688 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07007689
c_hpothufe599e92014-06-16 11:38:55 +05307690 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7691 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7692 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7693 eCSR_ENCRYPT_TYPE_NONE;
7694
Jeff Johnson295189b2012-06-20 16:38:30 -07007695 pConfig->RSNWPAReqIELength = 0;
7696 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307697 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007698 WLAN_EID_RSN);
7699 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307700 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007701 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7702 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7703 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307704 /* The actual processing may eventually be more extensive than
7705 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07007706 * by the app.
7707 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307708 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007709 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7710 &RSNEncryptType,
7711 &mcRSNEncryptType,
7712 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007713 &MFPCapable,
7714 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007715 pConfig->pRSNWPAReqIE[1]+2,
7716 pConfig->pRSNWPAReqIE );
7717
7718 if( VOS_STATUS_SUCCESS == status )
7719 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307720 /* Now copy over all the security attributes you have
7721 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007722 * */
7723 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7724 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7725 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7726 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307727 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007728 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007729 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7730 }
7731 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307732
Jeff Johnson295189b2012-06-20 16:38:30 -07007733 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7734 pBeacon->tail, pBeacon->tail_len);
7735
7736 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
7737 {
7738 if (pConfig->pRSNWPAReqIE)
7739 {
7740 /*Mixed mode WPA/WPA2*/
7741 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
7742 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7743 }
7744 else
7745 {
7746 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7747 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7748 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307749 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007750 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7751 &RSNEncryptType,
7752 &mcRSNEncryptType,
7753 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007754 &MFPCapable,
7755 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007756 pConfig->pRSNWPAReqIE[1]+2,
7757 pConfig->pRSNWPAReqIE );
7758
7759 if( VOS_STATUS_SUCCESS == status )
7760 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307761 /* Now copy over all the security attributes you have
7762 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007763 * */
7764 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7765 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7766 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7767 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307768 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007769 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007770 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7771 }
7772 }
7773 }
7774
Jeff Johnson4416a782013-03-25 14:17:50 -07007775 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
7776 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
7777 return -EINVAL;
7778 }
7779
Jeff Johnson295189b2012-06-20 16:38:30 -07007780 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
7781
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007782#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007783 if (params->ssid != NULL)
7784 {
7785 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
7786 pConfig->SSIDinfo.ssid.length = params->ssid_len;
7787 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7788 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7789 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007790#else
7791 if (ssid != NULL)
7792 {
7793 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
7794 pConfig->SSIDinfo.ssid.length = ssid_len;
7795 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7796 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7797 }
7798#endif
7799
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307800 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07007801 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307802
Jeff Johnson295189b2012-06-20 16:38:30 -07007803 /* default value */
7804 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7805 pConfig->num_accept_mac = 0;
7806 pConfig->num_deny_mac = 0;
7807
7808 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7809 pBeacon->tail, pBeacon->tail_len);
7810
7811 /* pIe for black list is following form:
7812 type : 1 byte
7813 length : 1 byte
7814 OUI : 4 bytes
7815 acl type : 1 byte
7816 no of mac addr in black list: 1 byte
7817 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307818 */
7819 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007820 {
7821 pConfig->SapMacaddr_acl = pIe[6];
7822 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007823 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007824 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307825 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7826 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007827 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7828 for (i = 0; i < pConfig->num_deny_mac; i++)
7829 {
7830 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7831 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307832 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007833 }
7834 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7835 pBeacon->tail, pBeacon->tail_len);
7836
7837 /* pIe for white list is following form:
7838 type : 1 byte
7839 length : 1 byte
7840 OUI : 4 bytes
7841 acl type : 1 byte
7842 no of mac addr in white list: 1 byte
7843 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307844 */
7845 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007846 {
7847 pConfig->SapMacaddr_acl = pIe[6];
7848 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007849 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007850 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307851 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7852 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007853 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7854 for (i = 0; i < pConfig->num_accept_mac; i++)
7855 {
7856 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7857 acl_entry++;
7858 }
7859 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307860
Jeff Johnson295189b2012-06-20 16:38:30 -07007861 wlan_hdd_set_sapHwmode(pHostapdAdapter);
7862
Jeff Johnsone7245742012-09-05 17:12:55 -07007863#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007864 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307865 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
7866 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05307867 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
7868 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007869 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
7870 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307871 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
7872 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07007873 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307874 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07007875 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307876 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007877
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307878 /* If ACS disable and selected channel <= 14
7879 * OR
7880 * ACS enabled and ACS operating band is choosen as 2.4
7881 * AND
7882 * VHT in 2.4G Disabled
7883 * THEN
7884 * Fallback to 11N mode
7885 */
7886 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
7887 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05307888 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307889 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007890 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307891 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
7892 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007893 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
7894 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007895 }
7896#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307897
Jeff Johnson295189b2012-06-20 16:38:30 -07007898 // ht_capab is not what the name conveys,this is used for protection bitmap
7899 pConfig->ht_capab =
7900 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
7901
7902 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
7903 {
7904 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7905 return -EINVAL;
7906 }
7907
7908 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307909 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07007910 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
7911 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307912 pConfig->obssProtEnabled =
7913 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07007914
Chet Lanctot8cecea22014-02-11 19:09:36 -08007915#ifdef WLAN_FEATURE_11W
7916 pConfig->mfpCapable = MFPCapable;
7917 pConfig->mfpRequired = MFPRequired;
7918 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
7919 pConfig->mfpCapable, pConfig->mfpRequired);
7920#endif
7921
Arif Hussain6d2a3322013-11-17 19:50:10 -08007922 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07007923 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007924 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
7925 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7926 (int)pConfig->channel);
7927 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
7928 pConfig->SapHw_mode, pConfig->privacy,
7929 pConfig->authType);
7930 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
7931 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7932 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7933 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07007934
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307935 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007936 {
7937 //Bss already started. just return.
7938 //TODO Probably it should update some beacon params.
7939 hddLog( LOGE, "Bss Already started...Ignore the request");
7940 EXIT();
7941 return 0;
7942 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307943
Agarwal Ashish51325b52014-06-16 16:50:49 +05307944 if (vos_max_concurrent_connections_reached()) {
7945 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7946 return -EINVAL;
7947 }
7948
Jeff Johnson295189b2012-06-20 16:38:30 -07007949 pConfig->persona = pHostapdAdapter->device_mode;
7950
Peng Xu2446a892014-09-05 17:21:18 +05307951 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
7952 if ( NULL != psmeConfig)
7953 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307954 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05307955 sme_GetConfigParam(hHal, psmeConfig);
7956 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307957#ifdef WLAN_FEATURE_AP_HT40_24G
7958 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7959 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
7960 && pHddCtx->cfg_ini->apHT40_24GEnabled)
7961 {
7962 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
7963 sme_UpdateConfig (hHal, psmeConfig);
7964 }
7965#endif
Peng Xu2446a892014-09-05 17:21:18 +05307966 vos_mem_free(psmeConfig);
7967 }
Peng Xuafc34e32014-09-25 13:23:55 +05307968 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05307969
Jeff Johnson295189b2012-06-20 16:38:30 -07007970 pSapEventCallback = hdd_hostapd_SAPEventCB;
7971 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
7972 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
7973 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007974 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007975 return -EINVAL;
7976 }
7977
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307978 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07007979 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7980
7981 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307982
Jeff Johnson295189b2012-06-20 16:38:30 -07007983 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307984 {
7985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007986 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07007987 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07007988 VOS_ASSERT(0);
7989 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307990
Jeff Johnson295189b2012-06-20 16:38:30 -07007991 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05307992 /* Initialize WMM configuation */
7993 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307994 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007995
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007996#ifdef WLAN_FEATURE_P2P_DEBUG
7997 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
7998 {
7999 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
8000 {
8001 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
8002 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08008003 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008004 }
8005 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
8006 {
8007 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
8008 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08008009 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008010 }
8011 }
8012#endif
8013
Jeff Johnson295189b2012-06-20 16:38:30 -07008014 pHostapdState->bCommit = TRUE;
8015 EXIT();
8016
8017 return 0;
8018}
8019
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008020#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308021static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308022 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008023 struct beacon_parameters *params)
8024{
8025 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308026 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308027 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008028
8029 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308030
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308031 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8032 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
8033 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308034 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
8035 hdd_device_modetoString(pAdapter->device_mode),
8036 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008037
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308038 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8039 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308040 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008041 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308042 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008043 }
8044
Agarwal Ashish51325b52014-06-16 16:50:49 +05308045 if (vos_max_concurrent_connections_reached()) {
8046 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8047 return -EINVAL;
8048 }
8049
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308050 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008051 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008052 )
8053 {
8054 beacon_data_t *old,*new;
8055
8056 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308057
Jeff Johnson295189b2012-06-20 16:38:30 -07008058 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308059 {
8060 hddLog(VOS_TRACE_LEVEL_WARN,
8061 FL("already beacon info added to session(%d)"),
8062 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008063 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308064 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008065
8066 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
8067
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308068 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07008069 {
8070 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008071 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008072 return -EINVAL;
8073 }
8074
8075 pAdapter->sessionCtx.ap.beacon = new;
8076
8077 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
8078 }
8079
8080 EXIT();
8081 return status;
8082}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308083
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308084static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
8085 struct net_device *dev,
8086 struct beacon_parameters *params)
8087{
8088 int ret;
8089
8090 vos_ssr_protect(__func__);
8091 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
8092 vos_ssr_unprotect(__func__);
8093
8094 return ret;
8095}
8096
8097static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008098 struct net_device *dev,
8099 struct beacon_parameters *params)
8100{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308101 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308102 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8103 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308104 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008105
8106 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308107
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308108 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8109 TRACE_CODE_HDD_CFG80211_SET_BEACON,
8110 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
8111 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8112 __func__, hdd_device_modetoString(pAdapter->device_mode),
8113 pAdapter->device_mode);
8114
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308115 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8116 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308117 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008118 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308119 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008120 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308121
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308122 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008123 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308124 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008125 {
8126 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308127
Jeff Johnson295189b2012-06-20 16:38:30 -07008128 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308129
Jeff Johnson295189b2012-06-20 16:38:30 -07008130 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308131 {
8132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8133 FL("session(%d) old and new heads points to NULL"),
8134 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008135 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308136 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008137
8138 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
8139
8140 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308141 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008142 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008143 return -EINVAL;
8144 }
8145
8146 pAdapter->sessionCtx.ap.beacon = new;
8147
8148 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
8149 }
8150
8151 EXIT();
8152 return status;
8153}
8154
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308155static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
8156 struct net_device *dev,
8157 struct beacon_parameters *params)
8158{
8159 int ret;
8160
8161 vos_ssr_protect(__func__);
8162 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
8163 vos_ssr_unprotect(__func__);
8164
8165 return ret;
8166}
8167
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008168#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8169
8170#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308171static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008172 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008173#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308174static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008175 struct net_device *dev)
8176#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008177{
8178 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07008179 hdd_context_t *pHddCtx = NULL;
8180 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308181 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308182 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008183
8184 ENTER();
8185
8186 if (NULL == pAdapter)
8187 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008189 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008190 return -ENODEV;
8191 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008192
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308193 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8194 TRACE_CODE_HDD_CFG80211_STOP_AP,
8195 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308196 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8197 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308198 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008199 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308200 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07008201 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008202
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008203 pScanInfo = &pHddCtx->scan_info;
8204
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308205 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8206 __func__, hdd_device_modetoString(pAdapter->device_mode),
8207 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008208
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308209 ret = wlan_hdd_scan_abort(pAdapter);
8210
Girish Gowli4bf7a632014-06-12 13:42:11 +05308211 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07008212 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8214 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308215
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308216 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07008217 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8219 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08008220
Jeff Johnsone7245742012-09-05 17:12:55 -07008221 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308222 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07008223 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308224 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008225 }
8226
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05308227 /* Delete all associated STAs before stopping AP/P2P GO */
8228 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05308229 hdd_hostapd_stop(dev);
8230
Jeff Johnson295189b2012-06-20 16:38:30 -07008231 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008232 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008233 )
8234 {
8235 beacon_data_t *old;
8236
8237 old = pAdapter->sessionCtx.ap.beacon;
8238
8239 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308240 {
8241 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8242 FL("session(%d) beacon data points to NULL"),
8243 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008244 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308245 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008246
Jeff Johnson295189b2012-06-20 16:38:30 -07008247 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008248
8249 mutex_lock(&pHddCtx->sap_lock);
8250 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8251 {
Jeff Johnson4416a782013-03-25 14:17:50 -07008252 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008253 {
8254 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8255
8256 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
8257
8258 if (!VOS_IS_STATUS_SUCCESS(status))
8259 {
8260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008261 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008262 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308263 }
8264 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008265 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05308266 /* BSS stopped, clear the active sessions for this device mode */
8267 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008268 }
8269 mutex_unlock(&pHddCtx->sap_lock);
8270
8271 if(status != VOS_STATUS_SUCCESS)
8272 {
8273 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008274 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008275 return -EINVAL;
8276 }
8277
Jeff Johnson4416a782013-03-25 14:17:50 -07008278 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008279 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
8280 ==eHAL_STATUS_FAILURE)
8281 {
8282 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008283 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008284 }
8285
Jeff Johnson4416a782013-03-25 14:17:50 -07008286 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008287 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8288 eANI_BOOLEAN_FALSE) )
8289 {
8290 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008291 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008292 }
8293
8294 // Reset WNI_CFG_PROBE_RSP Flags
8295 wlan_hdd_reset_prob_rspies(pAdapter);
8296
8297 pAdapter->sessionCtx.ap.beacon = NULL;
8298 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008299#ifdef WLAN_FEATURE_P2P_DEBUG
8300 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
8301 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
8302 {
8303 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
8304 "GO got removed");
8305 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
8306 }
8307#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008308 }
8309 EXIT();
8310 return status;
8311}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008312
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308313#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8314static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
8315 struct net_device *dev)
8316{
8317 int ret;
8318
8319 vos_ssr_protect(__func__);
8320 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
8321 vos_ssr_unprotect(__func__);
8322
8323 return ret;
8324}
8325#else
8326static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
8327 struct net_device *dev)
8328{
8329 int ret;
8330
8331 vos_ssr_protect(__func__);
8332 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
8333 vos_ssr_unprotect(__func__);
8334
8335 return ret;
8336}
8337#endif
8338
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008339#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
8340
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308341static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308342 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008343 struct cfg80211_ap_settings *params)
8344{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308345 hdd_adapter_t *pAdapter;
8346 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308347 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008348
8349 ENTER();
8350
Girish Gowlib143d7a2015-02-18 19:39:55 +05308351 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008352 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05308354 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308355 return -ENODEV;
8356 }
8357
8358 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8359 if (NULL == pAdapter)
8360 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308362 "%s: HDD adapter is Null", __func__);
8363 return -ENODEV;
8364 }
8365
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308366 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8367 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
8368 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308369 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8370 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308372 "%s: HDD adapter magic is invalid", __func__);
8373 return -ENODEV;
8374 }
8375
8376 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308377 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308378 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308379 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308380 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308381 }
8382
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308383 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
8384 __func__, hdd_device_modetoString(pAdapter->device_mode),
8385 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308386
8387 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008388 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008389 )
8390 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308391 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008392
8393 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308394
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008395 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308396 {
8397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8398 FL("already beacon info added to session(%d)"),
8399 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008400 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308401 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008402
Girish Gowlib143d7a2015-02-18 19:39:55 +05308403#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8404 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8405 &new,
8406 &params->beacon);
8407#else
8408 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8409 &new,
8410 &params->beacon,
8411 params->dtim_period);
8412#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008413
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308414 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008415 {
8416 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308417 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008418 return -EINVAL;
8419 }
8420 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08008421#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07008422 wlan_hdd_cfg80211_set_channel(wiphy, dev,
8423#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
8424 params->channel, params->channel_type);
8425#else
8426 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
8427#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08008428#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008429 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308430 params->ssid_len, params->hidden_ssid,
8431 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008432 }
8433
8434 EXIT();
8435 return status;
8436}
8437
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308438static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
8439 struct net_device *dev,
8440 struct cfg80211_ap_settings *params)
8441{
8442 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008443
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308444 vos_ssr_protect(__func__);
8445 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
8446 vos_ssr_unprotect(__func__);
8447
8448 return ret;
8449}
8450
8451static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008452 struct net_device *dev,
8453 struct cfg80211_beacon_data *params)
8454{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308455 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308456 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308457 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008458
8459 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308460
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308461 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8462 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
8463 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08008464 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008465 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308466
8467 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8468 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308469 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008470 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308471 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008472 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008473
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308474 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008475 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308476 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008477 {
8478 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308479
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008480 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308481
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008482 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308483 {
8484 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8485 FL("session(%d) beacon data points to NULL"),
8486 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008487 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308488 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008489
8490 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
8491
8492 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308493 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008494 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008495 return -EINVAL;
8496 }
8497
8498 pAdapter->sessionCtx.ap.beacon = new;
8499
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308500 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
8501 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008502 }
8503
8504 EXIT();
8505 return status;
8506}
8507
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308508static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8509 struct net_device *dev,
8510 struct cfg80211_beacon_data *params)
8511{
8512 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008513
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308514 vos_ssr_protect(__func__);
8515 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8516 vos_ssr_unprotect(__func__);
8517
8518 return ret;
8519}
8520
8521#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008522
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308523static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008524 struct net_device *dev,
8525 struct bss_parameters *params)
8526{
8527 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308528 hdd_context_t *pHddCtx;
8529 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008530
8531 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308532
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308533 if (NULL == pAdapter)
8534 {
8535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8536 "%s: HDD adapter is Null", __func__);
8537 return -ENODEV;
8538 }
8539 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308540 ret = wlan_hdd_validate_context(pHddCtx);
8541 if (0 != ret)
8542 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308543 return ret;
8544 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308545 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8546 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
8547 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308548 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8549 __func__, hdd_device_modetoString(pAdapter->device_mode),
8550 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008551
8552 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008553 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308554 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008555 {
8556 /* ap_isolate == -1 means that in change bss, upper layer doesn't
8557 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308558 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07008559 {
8560 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308561 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008562 }
8563
8564 EXIT();
8565 return 0;
8566}
8567
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308568static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
8569 struct net_device *dev,
8570 struct bss_parameters *params)
8571{
8572 int ret;
8573
8574 vos_ssr_protect(__func__);
8575 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
8576 vos_ssr_unprotect(__func__);
8577
8578 return ret;
8579}
Kiet Lam10841362013-11-01 11:36:50 +05308580/* FUNCTION: wlan_hdd_change_country_code_cd
8581* to wait for contry code completion
8582*/
8583void* wlan_hdd_change_country_code_cb(void *pAdapter)
8584{
8585 hdd_adapter_t *call_back_pAdapter = pAdapter;
8586 complete(&call_back_pAdapter->change_country_code);
8587 return NULL;
8588}
8589
Jeff Johnson295189b2012-06-20 16:38:30 -07008590/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308591 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07008592 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
8593 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308594int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008595 struct net_device *ndev,
8596 enum nl80211_iftype type,
8597 u32 *flags,
8598 struct vif_params *params
8599 )
8600{
8601 struct wireless_dev *wdev;
8602 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008603 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07008604 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008605 tCsrRoamProfile *pRoamProfile = NULL;
8606 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308607 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008608 eMib_dot11DesiredBssType connectedBssType;
8609 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308610 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008611
8612 ENTER();
8613
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308614 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008615 {
8616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8617 "%s: Adapter context is null", __func__);
8618 return VOS_STATUS_E_FAILURE;
8619 }
8620
8621 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8622 if (!pHddCtx)
8623 {
8624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8625 "%s: HDD context is null", __func__);
8626 return VOS_STATUS_E_FAILURE;
8627 }
8628
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308629 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8630 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
8631 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308632 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308633 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07008634 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308635 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008636 }
8637
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308638 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8639 __func__, hdd_device_modetoString(pAdapter->device_mode),
8640 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008641
Agarwal Ashish51325b52014-06-16 16:50:49 +05308642 if (vos_max_concurrent_connections_reached()) {
8643 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8644 return -EINVAL;
8645 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308646 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07008647 wdev = ndev->ieee80211_ptr;
8648
8649#ifdef WLAN_BTAMP_FEATURE
8650 if((NL80211_IFTYPE_P2P_CLIENT == type)||
8651 (NL80211_IFTYPE_ADHOC == type)||
8652 (NL80211_IFTYPE_AP == type)||
8653 (NL80211_IFTYPE_P2P_GO == type))
8654 {
8655 pHddCtx->isAmpAllowed = VOS_FALSE;
8656 // stop AMP traffic
8657 status = WLANBAP_StopAmp();
8658 if(VOS_STATUS_SUCCESS != status )
8659 {
8660 pHddCtx->isAmpAllowed = VOS_TRUE;
8661 hddLog(VOS_TRACE_LEVEL_FATAL,
8662 "%s: Failed to stop AMP", __func__);
8663 return -EINVAL;
8664 }
8665 }
8666#endif //WLAN_BTAMP_FEATURE
8667 /* Reset the current device mode bit mask*/
8668 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8669
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +05308670 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
8671 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
8672 (type == NL80211_IFTYPE_P2P_GO)))
8673 {
8674 /* Notify Mode change in case of concurrency.
8675 * Below function invokes TDLS teardown Functionality Since TDLS is
8676 * not Supported in case of concurrency i.e Once P2P session
8677 * is detected disable offchannel and teardown TDLS links
8678 */
8679 hddLog(LOG1,
8680 FL("Device mode = %d Interface type = %d"),
8681 pAdapter->device_mode, type);
8682 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
8683 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +05308684
Jeff Johnson295189b2012-06-20 16:38:30 -07008685 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008686 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07008687 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008688 )
8689 {
8690 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008691 if (!pWextState)
8692 {
8693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8694 "%s: pWextState is null", __func__);
8695 return VOS_STATUS_E_FAILURE;
8696 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008697 pRoamProfile = &pWextState->roamProfile;
8698 LastBSSType = pRoamProfile->BSSType;
8699
8700 switch (type)
8701 {
8702 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008703 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008704 hddLog(VOS_TRACE_LEVEL_INFO,
8705 "%s: setting interface Type to INFRASTRUCTURE", __func__);
8706 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008707#ifdef WLAN_FEATURE_11AC
8708 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
8709 {
8710 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
8711 }
8712#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308713 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07008714 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008715 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008716 //Check for sub-string p2p to confirm its a p2p interface
8717 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308718 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +05308719#ifdef FEATURE_WLAN_TDLS
8720 mutex_lock(&pHddCtx->tdls_lock);
8721 wlan_hdd_tdls_exit(pAdapter, TRUE);
8722 mutex_unlock(&pHddCtx->tdls_lock);
8723#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008724 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8725 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8726 }
8727 else
8728 {
8729 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008730 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008731 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008732 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05308733
Jeff Johnson295189b2012-06-20 16:38:30 -07008734 case NL80211_IFTYPE_ADHOC:
8735 hddLog(VOS_TRACE_LEVEL_INFO,
8736 "%s: setting interface Type to ADHOC", __func__);
8737 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
8738 pRoamProfile->phyMode =
8739 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07008740 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008741 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05308742 hdd_set_ibss_ops( pAdapter );
8743 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +05308744
8745 status = hdd_sta_id_hash_attach(pAdapter);
8746 if (VOS_STATUS_SUCCESS != status) {
8747 hddLog(VOS_TRACE_LEVEL_ERROR,
8748 FL("Failed to initialize hash for IBSS"));
8749 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008750 break;
8751
8752 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008753 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008754 {
8755 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8756 "%s: setting interface Type to %s", __func__,
8757 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
8758
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008759 //Cancel any remain on channel for GO mode
8760 if (NL80211_IFTYPE_P2P_GO == type)
8761 {
8762 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
8763 }
Mohit Khanna0f232092012-09-11 14:46:08 -07008764 if (NL80211_IFTYPE_AP == type)
8765 {
8766 /* As Loading WLAN Driver one interface being created for p2p device
8767 * address. This will take one HW STA and the max number of clients
8768 * that can connect to softAP will be reduced by one. so while changing
8769 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
8770 * interface as it is not required in SoftAP mode.
8771 */
8772
8773 // Get P2P Adapter
8774 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
8775
8776 if (pP2pAdapter)
8777 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308778 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05308779 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07008780 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
8781 }
8782 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05308783 //Disable IMPS & BMPS for SAP/GO
8784 if(VOS_STATUS_E_FAILURE ==
8785 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
8786 {
8787 //Fail to Exit BMPS
8788 VOS_ASSERT(0);
8789 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05308790
8791 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
8792
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308793#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07008794
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308795 /* A Mutex Lock is introduced while changing the mode to
8796 * protect the concurrent access for the Adapters by TDLS
8797 * module.
8798 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308799 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308800#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008801 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05308802 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008803 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07008804 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8805 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308806#ifdef FEATURE_WLAN_TDLS
8807 mutex_unlock(&pHddCtx->tdls_lock);
8808#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008809 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
8810 (pConfig->apRandomBssidEnabled))
8811 {
8812 /* To meet Android requirements create a randomized
8813 MAC address of the form 02:1A:11:Fx:xx:xx */
8814 get_random_bytes(&ndev->dev_addr[3], 3);
8815 ndev->dev_addr[0] = 0x02;
8816 ndev->dev_addr[1] = 0x1A;
8817 ndev->dev_addr[2] = 0x11;
8818 ndev->dev_addr[3] |= 0xF0;
8819 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
8820 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08008821 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
8822 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008823 }
8824
Jeff Johnson295189b2012-06-20 16:38:30 -07008825 hdd_set_ap_ops( pAdapter->dev );
8826
Kiet Lam10841362013-11-01 11:36:50 +05308827 /* This is for only SAP mode where users can
8828 * control country through ini.
8829 * P2P GO follows station country code
8830 * acquired during the STA scanning. */
8831 if((NL80211_IFTYPE_AP == type) &&
8832 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
8833 {
8834 int status = 0;
8835 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
8836 "%s: setting country code from INI ", __func__);
8837 init_completion(&pAdapter->change_country_code);
8838 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
8839 (void *)(tSmeChangeCountryCallback)
8840 wlan_hdd_change_country_code_cb,
8841 pConfig->apCntryCode, pAdapter,
8842 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308843 eSIR_FALSE,
8844 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05308845 if (eHAL_STATUS_SUCCESS == status)
8846 {
8847 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308848 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05308849 &pAdapter->change_country_code,
8850 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308851 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05308852 {
8853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308854 FL("SME Timed out while setting country code %ld"),
8855 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08008856
8857 if (pHddCtx->isLogpInProgress)
8858 {
8859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8860 "%s: LOGP in Progress. Ignore!!!", __func__);
8861 return -EAGAIN;
8862 }
Kiet Lam10841362013-11-01 11:36:50 +05308863 }
8864 }
8865 else
8866 {
8867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008868 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05308869 return -EINVAL;
8870 }
8871 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008872 status = hdd_init_ap_mode(pAdapter);
8873 if(status != VOS_STATUS_SUCCESS)
8874 {
8875 hddLog(VOS_TRACE_LEVEL_FATAL,
8876 "%s: Error initializing the ap mode", __func__);
8877 return -EINVAL;
8878 }
8879 hdd_set_conparam(1);
8880
Nirav Shah7e3c8132015-06-22 23:51:42 +05308881 status = hdd_sta_id_hash_attach(pAdapter);
8882 if (VOS_STATUS_SUCCESS != status)
8883 {
8884 hddLog(VOS_TRACE_LEVEL_ERROR,
8885 FL("Failed to initialize hash for AP"));
8886 return -EINVAL;
8887 }
8888
Jeff Johnson295189b2012-06-20 16:38:30 -07008889 /*interface type changed update in wiphy structure*/
8890 if(wdev)
8891 {
8892 wdev->iftype = type;
8893 pHddCtx->change_iface = type;
8894 }
8895 else
8896 {
8897 hddLog(VOS_TRACE_LEVEL_ERROR,
8898 "%s: ERROR !!!! Wireless dev is NULL", __func__);
8899 return -EINVAL;
8900 }
8901 goto done;
8902 }
8903
8904 default:
8905 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8906 __func__);
8907 return -EOPNOTSUPP;
8908 }
8909 }
8910 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008911 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008912 )
8913 {
8914 switch(type)
8915 {
8916 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008917 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008918 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05308919
8920 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308921#ifdef FEATURE_WLAN_TDLS
8922
8923 /* A Mutex Lock is introduced while changing the mode to
8924 * protect the concurrent access for the Adapters by TDLS
8925 * module.
8926 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308927 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308928#endif
c_hpothu002231a2015-02-05 14:58:51 +05308929 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008930 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008931 //Check for sub-string p2p to confirm its a p2p interface
8932 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008933 {
8934 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8935 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8936 }
8937 else
8938 {
8939 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008940 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008941 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008942 hdd_set_conparam(0);
8943 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008944 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
8945 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308946#ifdef FEATURE_WLAN_TDLS
8947 mutex_unlock(&pHddCtx->tdls_lock);
8948#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308949 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008950 if( VOS_STATUS_SUCCESS != status )
8951 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07008952 /* In case of JB, for P2P-GO, only change interface will be called,
8953 * This is the right place to enable back bmps_imps()
8954 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308955 if (pHddCtx->hdd_wlan_suspended)
8956 {
8957 hdd_set_pwrparams(pHddCtx);
8958 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008959 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008960 goto done;
8961 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008962 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008963 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008964 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8965 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008966 goto done;
8967 default:
8968 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8969 __func__);
8970 return -EOPNOTSUPP;
8971
8972 }
8973
8974 }
8975 else
8976 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308977 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
8978 __func__, hdd_device_modetoString(pAdapter->device_mode),
8979 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008980 return -EOPNOTSUPP;
8981 }
8982
8983
8984 if(pRoamProfile)
8985 {
8986 if ( LastBSSType != pRoamProfile->BSSType )
8987 {
8988 /*interface type changed update in wiphy structure*/
8989 wdev->iftype = type;
8990
8991 /*the BSS mode changed, We need to issue disconnect
8992 if connected or in IBSS disconnect state*/
8993 if ( hdd_connGetConnectedBssType(
8994 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
8995 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
8996 {
8997 /*need to issue a disconnect to CSR.*/
8998 INIT_COMPLETION(pAdapter->disconnect_comp_var);
8999 if( eHAL_STATUS_SUCCESS ==
9000 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
9001 pAdapter->sessionId,
9002 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
9003 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309004 ret = wait_for_completion_interruptible_timeout(
9005 &pAdapter->disconnect_comp_var,
9006 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
9007 if (ret <= 0)
9008 {
9009 hddLog(VOS_TRACE_LEVEL_ERROR,
9010 FL("wait on disconnect_comp_var failed %ld"), ret);
9011 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009012 }
9013 }
9014 }
9015 }
9016
9017done:
9018 /*set bitmask based on updated value*/
9019 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07009020
9021 /* Only STA mode support TM now
9022 * all other mode, TM feature should be disabled */
9023 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
9024 (~VOS_STA & pHddCtx->concurrency_mode) )
9025 {
9026 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
9027 }
9028
Jeff Johnson295189b2012-06-20 16:38:30 -07009029#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309030 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05309031 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07009032 {
9033 //we are ok to do AMP
9034 pHddCtx->isAmpAllowed = VOS_TRUE;
9035 }
9036#endif //WLAN_BTAMP_FEATURE
9037 EXIT();
9038 return 0;
9039}
9040
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05309041/*
9042 * FUNCTION: wlan_hdd_cfg80211_change_iface
9043 * wrapper function to protect the actual implementation from SSR.
9044 */
9045int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
9046 struct net_device *ndev,
9047 enum nl80211_iftype type,
9048 u32 *flags,
9049 struct vif_params *params
9050 )
9051{
9052 int ret;
9053
9054 vos_ssr_protect(__func__);
9055 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
9056 vos_ssr_unprotect(__func__);
9057
9058 return ret;
9059}
9060
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009061#ifdef FEATURE_WLAN_TDLS
9062static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309063 struct net_device *dev,
9064#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9065 const u8 *mac,
9066#else
9067 u8 *mac,
9068#endif
9069 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009070{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009071 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009072 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309073 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309074 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05309075 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309076 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009077
9078 ENTER();
9079
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05309080 if (!dev) {
9081 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
9082 return -EINVAL;
9083 }
9084
9085 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9086 if (!pAdapter) {
9087 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
9088 return -EINVAL;
9089 }
9090
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309091 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009092 {
9093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9094 "Invalid arguments");
9095 return -EINVAL;
9096 }
Hoonki Lee27511902013-03-14 18:19:06 -07009097
9098 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
9099 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
9100 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309101 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07009102 "%s: TDLS mode is disabled OR not enabled in FW."
9103 MAC_ADDRESS_STR " Request declined.",
9104 __func__, MAC_ADDR_ARRAY(mac));
9105 return -ENOTSUPP;
9106 }
9107
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009108 if (pHddCtx->isLogpInProgress)
9109 {
9110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9111 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05309112 wlan_hdd_tdls_set_link_status(pAdapter,
9113 mac,
9114 eTDLS_LINK_IDLE,
9115 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009116 return -EBUSY;
9117 }
9118
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309119 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05309120 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009121
9122 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009124 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
9125 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309126 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009127 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009128 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309129 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009130
9131 /* in add station, we accept existing valid staId if there is */
9132 if ((0 == update) &&
9133 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
9134 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009135 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309136 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009137 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009138 " link_status %d. staId %d. add station ignored.",
9139 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
9140 return 0;
9141 }
9142 /* in change station, we accept only when staId is valid */
9143 if ((1 == update) &&
9144 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
9145 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
9146 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009148 "%s: " MAC_ADDRESS_STR
9149 " link status %d. staId %d. change station %s.",
9150 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
9151 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
9152 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009153 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009154
9155 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05309156 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009157 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9159 "%s: " MAC_ADDRESS_STR
9160 " TDLS setup is ongoing. Request declined.",
9161 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07009162 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009163 }
9164
9165 /* first to check if we reached to maximum supported TDLS peer.
9166 TODO: for now, return -EPERM looks working fine,
9167 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309168 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
9169 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009170 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9172 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309173 " TDLS Max peer already connected. Request declined."
9174 " Num of peers (%d), Max allowed (%d).",
9175 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
9176 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009177 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009178 }
9179 else
9180 {
9181 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309182 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009183 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009184 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009185 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9186 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
9187 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009188 return -EPERM;
9189 }
9190 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009191 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05309192 wlan_hdd_tdls_set_link_status(pAdapter,
9193 mac,
9194 eTDLS_LINK_CONNECTING,
9195 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009196
Jeff Johnsond75fe012013-04-06 10:53:06 -07009197 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309198 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009199 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009201 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009202 if(StaParams->htcap_present)
9203 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009205 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009207 "ht_capa->extended_capabilities: %0x",
9208 StaParams->HTCap.extendedHtCapInfo);
9209 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009211 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009213 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009214 if(StaParams->vhtcap_present)
9215 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009217 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
9218 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
9219 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
9220 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009221 {
9222 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009224 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309225 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009226 "[%d]: %x ", i, StaParams->supported_rates[i]);
9227 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07009228 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309229 else if ((1 == update) && (NULL == StaParams))
9230 {
9231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9232 "%s : update is true, but staParams is NULL. Error!", __func__);
9233 return -EPERM;
9234 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009235
9236 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
9237
9238 if (!update)
9239 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309240 /*Before adding sta make sure that device exited from BMPS*/
9241 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
9242 {
9243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9244 "%s: Adding tdls peer sta. Disable BMPS", __func__);
9245 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
9246 if (status != VOS_STATUS_SUCCESS) {
9247 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
9248 }
9249 }
9250
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309251 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009252 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309253 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309254 hddLog(VOS_TRACE_LEVEL_ERROR,
9255 FL("Failed to add TDLS peer STA. Enable Bmps"));
9256 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309257 return -EPERM;
9258 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009259 }
9260 else
9261 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309262 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009263 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309264 if (ret != eHAL_STATUS_SUCCESS) {
9265 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
9266 return -EPERM;
9267 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009268 }
9269
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309270 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009271 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
9272
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309273 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009274 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009275 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309276 "%s: timeout waiting for tdls add station indication %ld",
9277 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009278 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009279 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309280
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009281 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
9282 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009284 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009285 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009286 }
9287
9288 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07009289
9290error:
Atul Mittal115287b2014-07-08 13:26:33 +05309291 wlan_hdd_tdls_set_link_status(pAdapter,
9292 mac,
9293 eTDLS_LINK_IDLE,
9294 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009295 return -EPERM;
9296
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009297}
9298#endif
9299
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309300static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009301 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309302#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9303 const u8 *mac,
9304#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009305 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309306#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009307 struct station_parameters *params)
9308{
9309 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309310 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309311 hdd_context_t *pHddCtx;
9312 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009313 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309314 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009315#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009316 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009317 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309318 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009319#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009320
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309321 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309322
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309323 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
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_CHANGE_STATION,
9333 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05309334 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05309335
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309336 ret = wlan_hdd_validate_context(pHddCtx);
9337 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05309338 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309339 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309340 }
9341
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309342 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9343
9344 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009345 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9347 "invalid HDD station context");
9348 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009349 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009350 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
9351
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009352 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
9353 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07009354 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009355 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07009356 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309357 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07009358 WLANTL_STA_AUTHENTICATED);
9359
Gopichand Nakkala29149562013-05-10 21:43:41 +05309360 if (status != VOS_STATUS_SUCCESS)
9361 {
9362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9363 "%s: Not able to change TL state to AUTHENTICATED", __func__);
9364 return -EINVAL;
9365 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009366 }
9367 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07009368 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9369 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309370#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009371 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
9372 StaParams.capability = params->capability;
9373 StaParams.uapsd_queues = params->uapsd_queues;
9374 StaParams.max_sp = params->max_sp;
9375
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309376 /* Convert (first channel , number of channels) tuple to
9377 * the total list of channels. This goes with the assumption
9378 * that if the first channel is < 14, then the next channels
9379 * are an incremental of 1 else an incremental of 4 till the number
9380 * of channels.
9381 */
9382 if (0 != params->supported_channels_len) {
9383 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
9384 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
9385 {
9386 int wifi_chan_index;
9387 StaParams.supported_channels[j] = params->supported_channels[i];
9388 wifi_chan_index =
9389 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
9390 no_of_channels = params->supported_channels[i+1];
9391 for(k=1; k <= no_of_channels; k++)
9392 {
9393 StaParams.supported_channels[j+1] =
9394 StaParams.supported_channels[j] + wifi_chan_index;
9395 j+=1;
9396 }
9397 }
9398 StaParams.supported_channels_len = j;
9399 }
9400 vos_mem_copy(StaParams.supported_oper_classes,
9401 params->supported_oper_classes,
9402 params->supported_oper_classes_len);
9403 StaParams.supported_oper_classes_len =
9404 params->supported_oper_classes_len;
9405
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009406 if (0 != params->ext_capab_len)
9407 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
9408 sizeof(StaParams.extn_capability));
9409
9410 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009411 {
9412 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009413 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009414 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009415
9416 StaParams.supported_rates_len = params->supported_rates_len;
9417
9418 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
9419 * The supported_rates array , for all the structures propogating till Add Sta
9420 * to the firmware has to be modified , if the supplicant (ieee80211) is
9421 * modified to send more rates.
9422 */
9423
9424 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
9425 */
9426 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
9427 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
9428
9429 if (0 != StaParams.supported_rates_len) {
9430 int i = 0;
9431 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
9432 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009433 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009434 "Supported Rates with Length %d", StaParams.supported_rates_len);
9435 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009437 "[%d]: %0x", i, StaParams.supported_rates[i]);
9438 }
9439
9440 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009441 {
9442 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009443 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009444 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009445
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009446 if (0 != params->ext_capab_len ) {
9447 /*Define A Macro : TODO Sunil*/
9448 if ((1<<4) & StaParams.extn_capability[3]) {
9449 isBufSta = 1;
9450 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309451 /* TDLS Channel Switching Support */
9452 if ((1<<6) & StaParams.extn_capability[3]) {
9453 isOffChannelSupported = 1;
9454 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009455 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309456 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
9457 &StaParams, isBufSta,
9458 isOffChannelSupported);
9459
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309460 if (VOS_STATUS_SUCCESS != status) {
9461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9462 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
9463 return -EINVAL;
9464 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009465 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
9466
9467 if (VOS_STATUS_SUCCESS != status) {
9468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9469 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
9470 return -EINVAL;
9471 }
9472 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009473#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05309474 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009475 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009476 return status;
9477}
9478
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309479#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
9480static int wlan_hdd_change_station(struct wiphy *wiphy,
9481 struct net_device *dev,
9482 const u8 *mac,
9483 struct station_parameters *params)
9484#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309485static int wlan_hdd_change_station(struct wiphy *wiphy,
9486 struct net_device *dev,
9487 u8 *mac,
9488 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309489#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309490{
9491 int ret;
9492
9493 vos_ssr_protect(__func__);
9494 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
9495 vos_ssr_unprotect(__func__);
9496
9497 return ret;
9498}
9499
Jeff Johnson295189b2012-06-20 16:38:30 -07009500/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309501 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009502 * This function is used to initialize the key information
9503 */
9504#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309505static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009506 struct net_device *ndev,
9507 u8 key_index, bool pairwise,
9508 const u8 *mac_addr,
9509 struct key_params *params
9510 )
9511#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309512static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009513 struct net_device *ndev,
9514 u8 key_index, const u8 *mac_addr,
9515 struct key_params *params
9516 )
9517#endif
9518{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009519 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07009520 tCsrRoamSetKey setKey;
9521 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309522 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009523 v_U32_t roamId= 0xFF;
9524 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009525 hdd_hostapd_state_t *pHostapdState;
9526 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009527 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309528 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009529
9530 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309531
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309532 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9533 TRACE_CODE_HDD_CFG80211_ADD_KEY,
9534 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309535 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9536 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309537 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009538 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309539 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009540 }
9541
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309542 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9543 __func__, hdd_device_modetoString(pAdapter->device_mode),
9544 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009545
9546 if (CSR_MAX_NUM_KEY <= key_index)
9547 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009548 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009549 key_index);
9550
9551 return -EINVAL;
9552 }
9553
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009554 if (CSR_MAX_KEY_LEN < params->key_len)
9555 {
9556 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
9557 params->key_len);
9558
9559 return -EINVAL;
9560 }
9561
9562 hddLog(VOS_TRACE_LEVEL_INFO,
9563 "%s: called with key index = %d & key length %d",
9564 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009565
9566 /*extract key idx, key len and key*/
9567 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9568 setKey.keyId = key_index;
9569 setKey.keyLength = params->key_len;
9570 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
9571
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009572 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009573 {
9574 case WLAN_CIPHER_SUITE_WEP40:
9575 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
9576 break;
9577
9578 case WLAN_CIPHER_SUITE_WEP104:
9579 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
9580 break;
9581
9582 case WLAN_CIPHER_SUITE_TKIP:
9583 {
9584 u8 *pKey = &setKey.Key[0];
9585 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
9586
9587 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
9588
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009589 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07009590
9591 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009592 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009593 |--------------|----------|----------|
9594 <---16bytes---><--8bytes--><--8bytes-->
9595
9596 */
9597 /*Sme expects the 32 bytes key to be in the below order
9598
9599 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009600 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009601 |--------------|----------|----------|
9602 <---16bytes---><--8bytes--><--8bytes-->
9603 */
9604 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009605 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07009606
9607 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009608 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009609
9610 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009611 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009612
9613
9614 break;
9615 }
9616
9617 case WLAN_CIPHER_SUITE_CCMP:
9618 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
9619 break;
9620
9621#ifdef FEATURE_WLAN_WAPI
9622 case WLAN_CIPHER_SUITE_SMS4:
9623 {
9624 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9625 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
9626 params->key, params->key_len);
9627 return 0;
9628 }
9629#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009630
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009631#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009632 case WLAN_CIPHER_SUITE_KRK:
9633 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
9634 break;
9635#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009636
9637#ifdef WLAN_FEATURE_11W
9638 case WLAN_CIPHER_SUITE_AES_CMAC:
9639 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07009640 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07009641#endif
9642
Jeff Johnson295189b2012-06-20 16:38:30 -07009643 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009644 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009645 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309646 status = -EOPNOTSUPP;
9647 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009648 }
9649
9650 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
9651 __func__, setKey.encType);
9652
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009653 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07009654#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9655 (!pairwise)
9656#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009657 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07009658#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009659 )
9660 {
9661 /* set group key*/
9662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9663 "%s- %d: setting Broadcast key",
9664 __func__, __LINE__);
9665 setKey.keyDirection = eSIR_RX_ONLY;
9666 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9667 }
9668 else
9669 {
9670 /* set pairwise key*/
9671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9672 "%s- %d: setting pairwise key",
9673 __func__, __LINE__);
9674 setKey.keyDirection = eSIR_TX_RX;
9675 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9676 }
9677 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
9678 {
9679 setKey.keyDirection = eSIR_TX_RX;
9680 /*Set the group key*/
9681 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9682 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07009683
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009684 if ( 0 != status )
9685 {
9686 hddLog(VOS_TRACE_LEVEL_ERROR,
9687 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309688 status = -EINVAL;
9689 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009690 }
9691 /*Save the keys here and call sme_RoamSetKey for setting
9692 the PTK after peer joins the IBSS network*/
9693 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
9694 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309695 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009696 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05309697 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
9698 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
9699 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009700 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009701 if( pHostapdState->bssState == BSS_START )
9702 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009703 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9704 vos_status = wlan_hdd_check_ula_done(pAdapter);
9705
9706 if ( vos_status != VOS_STATUS_SUCCESS )
9707 {
9708 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9709 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9710 __LINE__, vos_status );
9711
9712 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9713
9714 status = -EINVAL;
9715 goto end;
9716 }
9717
Jeff Johnson295189b2012-06-20 16:38:30 -07009718 status = WLANSAP_SetKeySta( pVosContext, &setKey);
9719
9720 if ( status != eHAL_STATUS_SUCCESS )
9721 {
9722 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9723 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9724 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309725 status = -EINVAL;
9726 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009727 }
9728 }
9729
9730 /* Saving WEP keys */
9731 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
9732 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
9733 {
9734 //Save the wep key in ap context. Issue setkey after the BSS is started.
9735 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9736 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
9737 }
9738 else
9739 {
9740 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009741 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009742 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
9743 }
9744 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009745 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
9746 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009747 {
9748 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9749 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9750
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309751#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9752 if (!pairwise)
9753#else
9754 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9755#endif
9756 {
9757 /* set group key*/
9758 if (pHddStaCtx->roam_info.deferKeyComplete)
9759 {
9760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9761 "%s- %d: Perform Set key Complete",
9762 __func__, __LINE__);
9763 hdd_PerformRoamSetKeyComplete(pAdapter);
9764 }
9765 }
9766
Jeff Johnson295189b2012-06-20 16:38:30 -07009767 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
9768
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08009769 pWextState->roamProfile.Keys.defaultIndex = key_index;
9770
9771
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009772 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009773 params->key, params->key_len);
9774
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309775
Jeff Johnson295189b2012-06-20 16:38:30 -07009776 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9777
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309778 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009779 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309780 __func__, setKey.peerMac[0], setKey.peerMac[1],
9781 setKey.peerMac[2], setKey.peerMac[3],
9782 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009783 setKey.keyDirection);
9784
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009785 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +05309786
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009787 if ( vos_status != VOS_STATUS_SUCCESS )
9788 {
9789 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009790 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9791 __LINE__, vos_status );
9792
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009793 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009794
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009795 status = -EINVAL;
9796 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009797
9798 }
9799
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009800#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309801 /* The supplicant may attempt to set the PTK once pre-authentication
9802 is done. Save the key in the UMAC and include it in the ADD BSS
9803 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009804 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309805 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009806 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309807 hddLog(VOS_TRACE_LEVEL_INFO_MED,
9808 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309809 status = 0;
9810 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309811 }
9812 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
9813 {
9814 hddLog(VOS_TRACE_LEVEL_ERROR,
9815 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309816 status = -EINVAL;
9817 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009818 }
9819#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07009820
9821 /* issue set key request to SME*/
9822 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9823 pAdapter->sessionId, &setKey, &roamId );
9824
9825 if ( 0 != status )
9826 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309827 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009828 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
9829 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309830 status = -EINVAL;
9831 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009832 }
9833
9834
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309835 /* in case of IBSS as there was no information available about WEP keys during
9836 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07009837 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309838 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
9839 !( ( IW_AUTH_KEY_MGMT_802_1X
9840 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07009841 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
9842 )
9843 &&
9844 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
9845 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
9846 )
9847 )
9848 {
9849 setKey.keyDirection = eSIR_RX_ONLY;
9850 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9851
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309852 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009853 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309854 __func__, setKey.peerMac[0], setKey.peerMac[1],
9855 setKey.peerMac[2], setKey.peerMac[3],
9856 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009857 setKey.keyDirection);
9858
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309859 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009860 pAdapter->sessionId, &setKey, &roamId );
9861
9862 if ( 0 != status )
9863 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309864 hddLog(VOS_TRACE_LEVEL_ERROR,
9865 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009866 __func__, status);
9867 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309868 status = -EINVAL;
9869 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009870 }
9871 }
9872 }
9873
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309874end:
9875 /* Need to clear any trace of key value in the memory.
9876 * Thus zero out the memory even though it is local
9877 * variable.
9878 */
9879 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309880 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309881 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009882}
9883
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309884#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9885static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9886 struct net_device *ndev,
9887 u8 key_index, bool pairwise,
9888 const u8 *mac_addr,
9889 struct key_params *params
9890 )
9891#else
9892static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9893 struct net_device *ndev,
9894 u8 key_index, const u8 *mac_addr,
9895 struct key_params *params
9896 )
9897#endif
9898{
9899 int ret;
9900 vos_ssr_protect(__func__);
9901#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9902 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
9903 mac_addr, params);
9904#else
9905 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
9906 params);
9907#endif
9908 vos_ssr_unprotect(__func__);
9909
9910 return ret;
9911}
9912
Jeff Johnson295189b2012-06-20 16:38:30 -07009913/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309914 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009915 * This function is used to get the key information
9916 */
9917#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309918static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309919 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009920 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309921 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009922 const u8 *mac_addr, void *cookie,
9923 void (*callback)(void *cookie, struct key_params*)
9924 )
9925#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309926static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309927 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009928 struct net_device *ndev,
9929 u8 key_index, const u8 *mac_addr, void *cookie,
9930 void (*callback)(void *cookie, struct key_params*)
9931 )
9932#endif
9933{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309934 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309935 hdd_wext_state_t *pWextState = NULL;
9936 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009937 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309938 hdd_context_t *pHddCtx;
9939 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009940
9941 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309942
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309943 if (NULL == pAdapter)
9944 {
9945 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9946 "%s: HDD adapter is Null", __func__);
9947 return -ENODEV;
9948 }
9949
9950 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9951 ret = wlan_hdd_validate_context(pHddCtx);
9952 if (0 != ret)
9953 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309954 return ret;
9955 }
9956
9957 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9958 pRoamProfile = &(pWextState->roamProfile);
9959
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309960 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9961 __func__, hdd_device_modetoString(pAdapter->device_mode),
9962 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309963
Jeff Johnson295189b2012-06-20 16:38:30 -07009964 memset(&params, 0, sizeof(params));
9965
9966 if (CSR_MAX_NUM_KEY <= key_index)
9967 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309968 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07009969 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309970 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009971
9972 switch(pRoamProfile->EncryptionType.encryptionType[0])
9973 {
9974 case eCSR_ENCRYPT_TYPE_NONE:
9975 params.cipher = IW_AUTH_CIPHER_NONE;
9976 break;
9977
9978 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
9979 case eCSR_ENCRYPT_TYPE_WEP40:
9980 params.cipher = WLAN_CIPHER_SUITE_WEP40;
9981 break;
9982
9983 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
9984 case eCSR_ENCRYPT_TYPE_WEP104:
9985 params.cipher = WLAN_CIPHER_SUITE_WEP104;
9986 break;
9987
9988 case eCSR_ENCRYPT_TYPE_TKIP:
9989 params.cipher = WLAN_CIPHER_SUITE_TKIP;
9990 break;
9991
9992 case eCSR_ENCRYPT_TYPE_AES:
9993 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
9994 break;
9995
9996 default:
9997 params.cipher = IW_AUTH_CIPHER_NONE;
9998 break;
9999 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010000
c_hpothuaaf19692014-05-17 17:01:48 +053010001 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10002 TRACE_CODE_HDD_CFG80211_GET_KEY,
10003 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010004
Jeff Johnson295189b2012-06-20 16:38:30 -070010005 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
10006 params.seq_len = 0;
10007 params.seq = NULL;
10008 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
10009 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010010 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010011 return 0;
10012}
10013
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010014#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10015static int wlan_hdd_cfg80211_get_key(
10016 struct wiphy *wiphy,
10017 struct net_device *ndev,
10018 u8 key_index, bool pairwise,
10019 const u8 *mac_addr, void *cookie,
10020 void (*callback)(void *cookie, struct key_params*)
10021 )
10022#else
10023static int wlan_hdd_cfg80211_get_key(
10024 struct wiphy *wiphy,
10025 struct net_device *ndev,
10026 u8 key_index, const u8 *mac_addr, void *cookie,
10027 void (*callback)(void *cookie, struct key_params*)
10028 )
10029#endif
10030{
10031 int ret;
10032
10033 vos_ssr_protect(__func__);
10034#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10035 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
10036 mac_addr, cookie, callback);
10037#else
10038 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
10039 callback);
10040#endif
10041 vos_ssr_unprotect(__func__);
10042
10043 return ret;
10044}
10045
Jeff Johnson295189b2012-06-20 16:38:30 -070010046/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010047 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 * This function is used to delete the key information
10049 */
10050#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010051static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010052 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010053 u8 key_index,
10054 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070010055 const u8 *mac_addr
10056 )
10057#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010058static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010059 struct net_device *ndev,
10060 u8 key_index,
10061 const u8 *mac_addr
10062 )
10063#endif
10064{
10065 int status = 0;
10066
10067 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010068 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070010069 //it is observed that this is invalidating peer
10070 //key index whenever re-key is done. This is affecting data link.
10071 //It should be ok to ignore del_key.
10072#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010073 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
10074 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010075 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
10076 tCsrRoamSetKey setKey;
10077 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010078
Jeff Johnson295189b2012-06-20 16:38:30 -070010079 ENTER();
10080
10081 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
10082 __func__,pAdapter->device_mode);
10083
10084 if (CSR_MAX_NUM_KEY <= key_index)
10085 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010086 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010087 key_index);
10088
10089 return -EINVAL;
10090 }
10091
10092 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10093 setKey.keyId = key_index;
10094
10095 if (mac_addr)
10096 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
10097 else
10098 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
10099
10100 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
10101
10102 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010103 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010104 )
10105 {
10106
10107 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070010108 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10109 if( pHostapdState->bssState == BSS_START)
10110 {
10111 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010112
Jeff Johnson295189b2012-06-20 16:38:30 -070010113 if ( status != eHAL_STATUS_SUCCESS )
10114 {
10115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10116 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
10117 __LINE__, status );
10118 }
10119 }
10120 }
10121 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010122 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070010123 )
10124 {
10125 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10126
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010127 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
10128
10129 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070010130 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010131 __func__, setKey.peerMac[0], setKey.peerMac[1],
10132 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070010133 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010134 if(pAdapter->sessionCtx.station.conn_info.connState ==
10135 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070010136 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010137 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010138 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010139
Jeff Johnson295189b2012-06-20 16:38:30 -070010140 if ( 0 != status )
10141 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010142 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010143 "%s: sme_RoamSetKey failure, returned %d",
10144 __func__, status);
10145 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
10146 return -EINVAL;
10147 }
10148 }
10149 }
10150#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010151 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010152 return status;
10153}
10154
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010155#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10156static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10157 struct net_device *ndev,
10158 u8 key_index,
10159 bool pairwise,
10160 const u8 *mac_addr
10161 )
10162#else
10163static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10164 struct net_device *ndev,
10165 u8 key_index,
10166 const u8 *mac_addr
10167 )
10168#endif
10169{
10170 int ret;
10171
10172 vos_ssr_protect(__func__);
10173#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10174 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
10175 mac_addr);
10176#else
10177 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
10178#endif
10179 vos_ssr_unprotect(__func__);
10180
10181 return ret;
10182}
10183
Jeff Johnson295189b2012-06-20 16:38:30 -070010184/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010185 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010186 * This function is used to set the default tx key index
10187 */
10188#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010189static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010190 struct net_device *ndev,
10191 u8 key_index,
10192 bool unicast, bool multicast)
10193#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010194static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010195 struct net_device *ndev,
10196 u8 key_index)
10197#endif
10198{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010199 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010200 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010201 hdd_wext_state_t *pWextState;
10202 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010203 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010204
10205 ENTER();
10206
Gopichand Nakkala29149562013-05-10 21:43:41 +053010207 if ((NULL == pAdapter))
10208 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010210 "invalid adapter");
10211 return -EINVAL;
10212 }
10213
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010214 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10215 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
10216 pAdapter->sessionId, key_index));
10217
Gopichand Nakkala29149562013-05-10 21:43:41 +053010218 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10219 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10220
10221 if ((NULL == pWextState) || (NULL == pHddStaCtx))
10222 {
10223 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10224 "invalid Wext state or HDD context");
10225 return -EINVAL;
10226 }
10227
Arif Hussain6d2a3322013-11-17 19:50:10 -080010228 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010229 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010230
Jeff Johnson295189b2012-06-20 16:38:30 -070010231 if (CSR_MAX_NUM_KEY <= key_index)
10232 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010233 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010234 key_index);
10235
10236 return -EINVAL;
10237 }
10238
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010239 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10240 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010241 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010242 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010243 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010244 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010245
Jeff Johnson295189b2012-06-20 16:38:30 -070010246 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010247 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010248 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010249 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010250 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080010251 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010252 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080010253 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070010254 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010255 {
10256 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070010257 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010258
Jeff Johnson295189b2012-06-20 16:38:30 -070010259 tCsrRoamSetKey setKey;
10260 v_U32_t roamId= 0xFF;
10261 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010262
10263 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010264 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010265
Jeff Johnson295189b2012-06-20 16:38:30 -070010266 Keys->defaultIndex = (u8)key_index;
10267 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10268 setKey.keyId = key_index;
10269 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010270
10271 vos_mem_copy(&setKey.Key[0],
10272 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010273 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010274
Gopichand Nakkala29149562013-05-10 21:43:41 +053010275 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010276
10277 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070010278 &pHddStaCtx->conn_info.bssId[0],
10279 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010280
Gopichand Nakkala29149562013-05-10 21:43:41 +053010281 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
10282 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
10283 eCSR_ENCRYPT_TYPE_WEP104)
10284 {
10285 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
10286 even though ap is configured for WEP-40 encryption. In this canse the key length
10287 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
10288 type(104) and switching encryption type to 40*/
10289 pWextState->roamProfile.EncryptionType.encryptionType[0] =
10290 eCSR_ENCRYPT_TYPE_WEP40;
10291 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
10292 eCSR_ENCRYPT_TYPE_WEP40;
10293 }
10294
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010295 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070010296 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010297
Jeff Johnson295189b2012-06-20 16:38:30 -070010298 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010299 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010300 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010301
Jeff Johnson295189b2012-06-20 16:38:30 -070010302 if ( 0 != status )
10303 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010304 hddLog(VOS_TRACE_LEVEL_ERROR,
10305 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010306 status);
10307 return -EINVAL;
10308 }
10309 }
10310 }
10311
10312 /* In SoftAp mode setting key direction for default mode */
10313 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
10314 {
10315 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
10316 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
10317 (eCSR_ENCRYPT_TYPE_AES !=
10318 pWextState->roamProfile.EncryptionType.encryptionType[0])
10319 )
10320 {
10321 /* Saving key direction for default key index to TX default */
10322 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
10323 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
10324 }
10325 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010326 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010327 return status;
10328}
10329
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010330#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10331static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
10332 struct net_device *ndev,
10333 u8 key_index,
10334 bool unicast, bool multicast)
10335#else
10336static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
10337 struct net_device *ndev,
10338 u8 key_index)
10339#endif
10340{
10341 int ret;
10342 vos_ssr_protect(__func__);
10343#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10344 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
10345 multicast);
10346#else
10347 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
10348#endif
10349 vos_ssr_unprotect(__func__);
10350
10351 return ret;
10352}
10353
Jeff Johnson295189b2012-06-20 16:38:30 -070010354/*
10355 * FUNCTION: wlan_hdd_cfg80211_inform_bss
10356 * This function is used to inform the BSS details to nl80211 interface.
10357 */
10358static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
10359 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
10360{
10361 struct net_device *dev = pAdapter->dev;
10362 struct wireless_dev *wdev = dev->ieee80211_ptr;
10363 struct wiphy *wiphy = wdev->wiphy;
10364 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
10365 int chan_no;
10366 int ie_length;
10367 const char *ie;
10368 unsigned int freq;
10369 struct ieee80211_channel *chan;
10370 int rssi = 0;
10371 struct cfg80211_bss *bss = NULL;
10372
Jeff Johnson295189b2012-06-20 16:38:30 -070010373 if( NULL == pBssDesc )
10374 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010375 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010376 return bss;
10377 }
10378
10379 chan_no = pBssDesc->channelId;
10380 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
10381 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
10382
10383 if( NULL == ie )
10384 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010385 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010386 return bss;
10387 }
10388
10389#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10390 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10391 {
10392 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10393 }
10394 else
10395 {
10396 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10397 }
10398#else
10399 freq = ieee80211_channel_to_frequency(chan_no);
10400#endif
10401
10402 chan = __ieee80211_get_channel(wiphy, freq);
10403
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053010404 if (!chan) {
10405 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
10406 return NULL;
10407 }
10408
Abhishek Singhaee43942014-06-16 18:55:47 +053010409 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070010410
Anand N Sunkad9f80b742015-07-30 20:05:51 +053010411 return cfg80211_inform_bss(wiphy, chan,
10412#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10413 CFG80211_BSS_FTYPE_UNKNOWN,
10414#endif
10415 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010416 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070010417 pBssDesc->capabilityInfo,
10418 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053010419 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070010420}
10421
10422
10423
10424/*
10425 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
10426 * This function is used to inform the BSS details to nl80211 interface.
10427 */
10428struct cfg80211_bss*
10429wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
10430 tSirBssDescription *bss_desc
10431 )
10432{
10433 /*
10434 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
10435 already exists in bss data base of cfg80211 for that particular BSS ID.
10436 Using cfg80211_inform_bss_frame to update the bss entry instead of
10437 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
10438 now there is no possibility to get the mgmt(probe response) frame from PE,
10439 converting bss_desc to ieee80211_mgmt(probe response) and passing to
10440 cfg80211_inform_bss_frame.
10441 */
10442 struct net_device *dev = pAdapter->dev;
10443 struct wireless_dev *wdev = dev->ieee80211_ptr;
10444 struct wiphy *wiphy = wdev->wiphy;
10445 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010446#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10447 qcom_ie_age *qie_age = NULL;
10448 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
10449#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010450 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010451#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010452 const char *ie =
10453 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
10454 unsigned int freq;
10455 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010456 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010457 struct cfg80211_bss *bss_status = NULL;
10458 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
10459 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070010460 hdd_context_t *pHddCtx;
10461 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070010462#ifdef WLAN_OPEN_SOURCE
10463 struct timespec ts;
10464#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010465
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010466
Wilson Yangf80a0542013-10-07 13:02:37 -070010467 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10468 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070010469 if (0 != status)
10470 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010471 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010472 }
10473
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010474 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070010475 if (!mgmt)
10476 {
10477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10478 "%s: memory allocation failed ", __func__);
10479 return NULL;
10480 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010481
Jeff Johnson295189b2012-06-20 16:38:30 -070010482 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010483
10484#ifdef WLAN_OPEN_SOURCE
10485 /* Android does not want the timestamp from the frame.
10486 Instead it wants a monotonic increasing value */
10487 get_monotonic_boottime(&ts);
10488 mgmt->u.probe_resp.timestamp =
10489 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
10490#else
10491 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010492 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
10493 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070010494
10495#endif
10496
Jeff Johnson295189b2012-06-20 16:38:30 -070010497 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
10498 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010499
10500#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10501 /* GPS Requirement: need age ie per entry. Using vendor specific. */
10502 /* Assuming this is the last IE, copy at the end */
10503 ie_length -=sizeof(qcom_ie_age);
10504 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
10505 qie_age->element_id = QCOM_VENDOR_IE_ID;
10506 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
10507 qie_age->oui_1 = QCOM_OUI1;
10508 qie_age->oui_2 = QCOM_OUI2;
10509 qie_age->oui_3 = QCOM_OUI3;
10510 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
10511 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
10512#endif
10513
Jeff Johnson295189b2012-06-20 16:38:30 -070010514 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053010515 if (bss_desc->fProbeRsp)
10516 {
10517 mgmt->frame_control |=
10518 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
10519 }
10520 else
10521 {
10522 mgmt->frame_control |=
10523 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
10524 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010525
10526#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010527 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010528 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
10529 {
10530 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10531 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010532 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010533 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
10534
10535 {
10536 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10537 }
10538 else
10539 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010540 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
10541 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070010542 kfree(mgmt);
10543 return NULL;
10544 }
10545#else
10546 freq = ieee80211_channel_to_frequency(chan_no);
10547#endif
10548 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010549 /*when the band is changed on the fly using the GUI, three things are done
10550 * 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)
10551 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
10552 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
10553 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
10554 * and discards the channels correponding to previous band and calls back with zero bss results.
10555 * 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
10556 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
10557 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
10558 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
10559 * So drop the bss and continue to next bss.
10560 */
10561 if(chan == NULL)
10562 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010563 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070010564 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010565 return NULL;
10566 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053010567 /*To keep the rssi icon of the connected AP in the scan window
10568 *and the rssi icon of the wireless networks in sync
10569 * */
10570 if (( eConnectionState_Associated ==
10571 pAdapter->sessionCtx.station.conn_info.connState ) &&
10572 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
10573 pAdapter->sessionCtx.station.conn_info.bssId,
10574 WNI_CFG_BSSID_LEN)) &&
10575 (pHddCtx->hdd_wlan_suspended == FALSE))
10576 {
10577 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
10578 rssi = (pAdapter->rssi * 100);
10579 }
10580 else
10581 {
10582 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
10583 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010584
Nirav Shah20ac06f2013-12-12 18:14:06 +053010585 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053010586 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
10587 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053010588
Jeff Johnson295189b2012-06-20 16:38:30 -070010589 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
10590 frame_len, rssi, GFP_KERNEL);
10591 kfree(mgmt);
10592 return bss_status;
10593}
10594
10595/*
10596 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
10597 * This function is used to update the BSS data base of CFG8011
10598 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010599struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010600 tCsrRoamInfo *pRoamInfo
10601 )
10602{
10603 tCsrRoamConnectedProfile roamProfile;
10604 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10605 struct cfg80211_bss *bss = NULL;
10606
10607 ENTER();
10608
10609 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
10610 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
10611
10612 if (NULL != roamProfile.pBssDesc)
10613 {
Girish Gowlif4b68022014-08-28 23:18:57 +053010614 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10615 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070010616
10617 if (NULL == bss)
10618 {
10619 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
10620 __func__);
10621 }
10622
10623 sme_RoamFreeConnectProfile(hHal, &roamProfile);
10624 }
10625 else
10626 {
10627 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
10628 __func__);
10629 }
10630 return bss;
10631}
10632
10633/*
10634 * FUNCTION: wlan_hdd_cfg80211_update_bss
10635 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010636static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
10637 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070010638 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010639{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010640 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010641 tCsrScanResultInfo *pScanResult;
10642 eHalStatus status = 0;
10643 tScanResultHandle pResult;
10644 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010645 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010646 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070010647 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010648
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010649 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10650 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
10651 NO_SESSION, pAdapter->sessionId));
10652
Wilson Yangf80a0542013-10-07 13:02:37 -070010653 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10654
10655 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070010656 {
Wilson Yangf80a0542013-10-07 13:02:37 -070010657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10658 "%s:LOGP in Progress. Ignore!!!",__func__);
10659 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010660 }
10661
Wilson Yangf80a0542013-10-07 13:02:37 -070010662
10663 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053010664 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070010665 {
10666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10667 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
10668 return VOS_STATUS_E_PERM;
10669 }
10670
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010671 if (pAdapter->request != NULL)
10672 {
10673 if ((pAdapter->request->n_ssids == 1)
10674 && (pAdapter->request->ssids != NULL)
10675 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
10676 is_p2p_scan = true;
10677 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010678 /*
10679 * start getting scan results and populate cgf80211 BSS database
10680 */
10681 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
10682
10683 /* no scan results */
10684 if (NULL == pResult)
10685 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010686 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
10687 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053010688 wlan_hdd_get_frame_logs(pAdapter,
10689 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070010690 return status;
10691 }
10692
10693 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
10694
10695 while (pScanResult)
10696 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010697 /*
10698 * cfg80211_inform_bss() is not updating ie field of bss entry, if
10699 * entry already exists in bss data base of cfg80211 for that
10700 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
10701 * bss entry instead of cfg80211_inform_bss, But this call expects
10702 * mgmt packet as input. As of now there is no possibility to get
10703 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070010704 * ieee80211_mgmt(probe response) and passing to c
10705 * fg80211_inform_bss_frame.
10706 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010707 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
10708 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
10709 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010710 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10711 continue; //Skip the non p2p bss entries
10712 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010713 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10714 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010715
Jeff Johnson295189b2012-06-20 16:38:30 -070010716
10717 if (NULL == bss_status)
10718 {
10719 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010720 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010721 }
10722 else
10723 {
Yue Maf49ba872013-08-19 12:04:25 -070010724 cfg80211_put_bss(
10725#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
10726 wiphy,
10727#endif
10728 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010729 }
10730
10731 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10732 }
10733
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010734 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010735 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010736 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010737}
10738
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010739void
10740hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
10741{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010742 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080010743 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010744} /****** end hddPrintMacAddr() ******/
10745
10746void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010747hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010748{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010749 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010750 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010751 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
10752 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
10753 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010754} /****** end hddPrintPmkId() ******/
10755
10756//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
10757//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
10758
10759//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
10760//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
10761
10762#define dump_bssid(bssid) \
10763 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010764 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
10765 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010766 }
10767
10768#define dump_pmkid(pMac, pmkid) \
10769 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010770 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
10771 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010772 }
10773
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070010774#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010775/*
10776 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
10777 * This function is used to notify the supplicant of a new PMKSA candidate.
10778 */
10779int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010780 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010781 int index, bool preauth )
10782{
Jeff Johnsone7245742012-09-05 17:12:55 -070010783#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010784 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010785 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010786
10787 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070010788 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010789
10790 if( NULL == pRoamInfo )
10791 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010792 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010793 return -EINVAL;
10794 }
10795
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010796 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
10797 {
10798 dump_bssid(pRoamInfo->bssid);
10799 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010800 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010801 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010802#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010803 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010804}
10805#endif //FEATURE_WLAN_LFR
10806
Yue Maef608272013-04-08 23:09:17 -070010807#ifdef FEATURE_WLAN_LFR_METRICS
10808/*
10809 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
10810 * 802.11r/LFR metrics reporting function to report preauth initiation
10811 *
10812 */
10813#define MAX_LFR_METRICS_EVENT_LENGTH 100
10814VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
10815 tCsrRoamInfo *pRoamInfo)
10816{
10817 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10818 union iwreq_data wrqu;
10819
10820 ENTER();
10821
10822 if (NULL == pAdapter)
10823 {
10824 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10825 return VOS_STATUS_E_FAILURE;
10826 }
10827
10828 /* create the event */
10829 memset(&wrqu, 0, sizeof(wrqu));
10830 memset(metrics_notification, 0, sizeof(metrics_notification));
10831
10832 wrqu.data.pointer = metrics_notification;
10833 wrqu.data.length = scnprintf(metrics_notification,
10834 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
10835 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10836
10837 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10838
10839 EXIT();
10840
10841 return VOS_STATUS_SUCCESS;
10842}
10843
10844/*
10845 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
10846 * 802.11r/LFR metrics reporting function to report preauth completion
10847 * or failure
10848 */
10849VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
10850 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
10851{
10852 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10853 union iwreq_data wrqu;
10854
10855 ENTER();
10856
10857 if (NULL == pAdapter)
10858 {
10859 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10860 return VOS_STATUS_E_FAILURE;
10861 }
10862
10863 /* create the event */
10864 memset(&wrqu, 0, sizeof(wrqu));
10865 memset(metrics_notification, 0, sizeof(metrics_notification));
10866
10867 scnprintf(metrics_notification, sizeof(metrics_notification),
10868 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
10869 MAC_ADDR_ARRAY(pRoamInfo->bssid));
10870
10871 if (1 == preauth_status)
10872 strncat(metrics_notification, " TRUE", 5);
10873 else
10874 strncat(metrics_notification, " FALSE", 6);
10875
10876 wrqu.data.pointer = metrics_notification;
10877 wrqu.data.length = strlen(metrics_notification);
10878
10879 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10880
10881 EXIT();
10882
10883 return VOS_STATUS_SUCCESS;
10884}
10885
10886/*
10887 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
10888 * 802.11r/LFR metrics reporting function to report handover initiation
10889 *
10890 */
10891VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
10892 tCsrRoamInfo *pRoamInfo)
10893{
10894 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10895 union iwreq_data wrqu;
10896
10897 ENTER();
10898
10899 if (NULL == pAdapter)
10900 {
10901 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10902 return VOS_STATUS_E_FAILURE;
10903 }
10904
10905 /* create the event */
10906 memset(&wrqu, 0, sizeof(wrqu));
10907 memset(metrics_notification, 0, sizeof(metrics_notification));
10908
10909 wrqu.data.pointer = metrics_notification;
10910 wrqu.data.length = scnprintf(metrics_notification,
10911 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
10912 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10913
10914 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10915
10916 EXIT();
10917
10918 return VOS_STATUS_SUCCESS;
10919}
10920#endif
10921
Jeff Johnson295189b2012-06-20 16:38:30 -070010922/*
10923 * FUNCTION: hdd_cfg80211_scan_done_callback
10924 * scanning callback function, called after finishing scan
10925 *
10926 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010927static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070010928 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
10929{
10930 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010931 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070010932 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010933 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010934 struct cfg80211_scan_request *req = NULL;
10935 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010936 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010937 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010938 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010939 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010940
10941 ENTER();
10942
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010943 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053010944 if (NULL == pHddCtx) {
10945 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010946 goto allow_suspend;
10947 }
10948
10949 pScanInfo = &pHddCtx->scan_info;
10950
Jeff Johnson295189b2012-06-20 16:38:30 -070010951 hddLog(VOS_TRACE_LEVEL_INFO,
10952 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080010953 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010954 __func__, halHandle, pContext, (int) scanId, (int) status);
10955
Kiet Lamac06e2c2013-10-23 16:25:07 +053010956 pScanInfo->mScanPendingCounter = 0;
10957
Jeff Johnson295189b2012-06-20 16:38:30 -070010958 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010959 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010960 &pScanInfo->scan_req_completion_event,
10961 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010962 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070010963 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010964 hddLog(VOS_TRACE_LEVEL_ERROR,
10965 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070010966 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010967 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010968 }
10969
Yue Maef608272013-04-08 23:09:17 -070010970 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010971 {
10972 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010973 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010974 }
10975
10976 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010977 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070010978 {
10979 hddLog(VOS_TRACE_LEVEL_INFO,
10980 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010981 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070010982 (int) scanId);
10983 }
10984
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010985 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010986 pAdapter);
10987
10988 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010989 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010990
10991
10992 /* If any client wait scan result through WEXT
10993 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010994 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070010995 {
10996 /* The other scan request waiting for current scan finish
10997 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010998 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010999 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011000 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070011001 }
11002 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011003 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070011004 {
11005 struct net_device *dev = pAdapter->dev;
11006 union iwreq_data wrqu;
11007 int we_event;
11008 char *msg;
11009
11010 memset(&wrqu, '\0', sizeof(wrqu));
11011 we_event = SIOCGIWSCAN;
11012 msg = NULL;
11013 wireless_send_event(dev, we_event, &wrqu, msg);
11014 }
11015 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011016 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011017
11018 /* Get the Scan Req */
11019 req = pAdapter->request;
11020
11021 if (!req)
11022 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011023 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011024 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011025 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011026 }
11027
Jeff Johnson295189b2012-06-20 16:38:30 -070011028 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011029 /* Scan is no longer pending */
11030 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011031
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011032 /* last_scan_timestamp is used to decide if new scan
11033 * is needed or not on station interface. If last station
11034 * scan time and new station scan time is less then
11035 * last_scan_timestamp ; driver will return cached scan.
11036 */
11037 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
11038 {
11039 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
11040
11041 if ( req->n_channels )
11042 {
11043 for (i = 0; i < req->n_channels ; i++ )
11044 {
11045 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
11046 }
11047 /* store no of channel scanned */
11048 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
11049 }
11050
11051 }
11052
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070011053 /*
11054 * cfg80211_scan_done informing NL80211 about completion
11055 * of scanning
11056 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011057 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
11058 {
11059 aborted = true;
11060 }
11061 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080011062 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070011063
Siddharth Bhal76972212014-10-15 16:22:51 +053011064 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
11065 /* Generate new random mac addr for next scan */
11066 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
11067 hdd_processSpoofMacAddrRequest(pHddCtx);
11068 }
11069
Jeff Johnsone7245742012-09-05 17:12:55 -070011070allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011071 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011072 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011073
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011074 /* Acquire wakelock to handle the case where APP's tries to suspend
11075 * immediatly after the driver gets connect request(i.e after scan)
11076 * from supplicant, this result in app's is suspending and not able
11077 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011078 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011079
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070011080#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011081 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070011082#endif
11083
Jeff Johnson295189b2012-06-20 16:38:30 -070011084 EXIT();
11085 return 0;
11086}
11087
11088/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053011089 * FUNCTION: hdd_isConnectionInProgress
11090 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011091 *
11092 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011093v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011094{
11095 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11096 hdd_station_ctx_t *pHddStaCtx = NULL;
11097 hdd_adapter_t *pAdapter = NULL;
11098 VOS_STATUS status = 0;
11099 v_U8_t staId = 0;
11100 v_U8_t *staMac = NULL;
11101
c_hpothu9b781ba2013-12-30 20:57:45 +053011102 if (TRUE == pHddCtx->btCoexModeSet)
11103 {
11104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053011105 FL("BTCoex Mode operation in progress"));
11106 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053011107 }
11108
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011109 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11110
11111 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11112 {
11113 pAdapter = pAdapterNode->pAdapter;
11114
11115 if( pAdapter )
11116 {
11117 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011118 "%s: Adapter with device mode %s (%d) exists",
11119 __func__, hdd_device_modetoString(pAdapter->device_mode),
11120 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011121 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053011122 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11123 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
11124 (eConnectionState_Connecting ==
11125 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11126 {
11127 hddLog(VOS_TRACE_LEVEL_ERROR,
11128 "%s: %p(%d) Connection is in progress", __func__,
11129 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11130 return VOS_TRUE;
11131 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011132 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053011133 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011134 {
11135 hddLog(VOS_TRACE_LEVEL_ERROR,
11136 "%s: %p(%d) Reassociation is in progress", __func__,
11137 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11138 return VOS_TRUE;
11139 }
11140 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011141 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11142 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011143 {
11144 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11145 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011146 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011147 {
11148 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
11149 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011150 "%s: client " MAC_ADDRESS_STR
11151 " is in the middle of WPS/EAPOL exchange.", __func__,
11152 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011153 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011154 }
11155 }
11156 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
11157 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
11158 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011159 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11160 ptSapContext pSapCtx = NULL;
11161 pSapCtx = VOS_GET_SAP_CB(pVosContext);
11162 if(pSapCtx == NULL){
11163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11164 FL("psapCtx is NULL"));
11165 return VOS_FALSE;
11166 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011167 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
11168 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011169 if ((pSapCtx->aStaInfo[staId].isUsed) &&
11170 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011171 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011172 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011173
11174 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011175 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
11176 "middle of WPS/EAPOL exchange.", __func__,
11177 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011178 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011179 }
11180 }
11181 }
11182 }
11183 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11184 pAdapterNode = pNext;
11185 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053011186 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011187}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011188
11189/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011190 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070011191 * this scan respond to scan trigger and update cfg80211 scan database
11192 * later, scan dump command can be used to recieve scan results
11193 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011194int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080011195#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11196 struct net_device *dev,
11197#endif
11198 struct cfg80211_scan_request *request)
11199{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011200 hdd_adapter_t *pAdapter = NULL;
11201 hdd_context_t *pHddCtx = NULL;
11202 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011203 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011204 tCsrScanRequest scanRequest;
11205 tANI_U8 *channelList = NULL, i;
11206 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011207 int status;
11208 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011209 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011210 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053011211 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011212 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011213 v_S7_t rssi=0;
11214 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011215
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011216#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
11217 struct net_device *dev = NULL;
11218 if (NULL == request)
11219 {
11220 hddLog(VOS_TRACE_LEVEL_ERROR,
11221 "%s: scan req param null", __func__);
11222 return -EINVAL;
11223 }
11224 dev = request->wdev->netdev;
11225#endif
11226
11227 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11228 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
11229 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11230
Jeff Johnson295189b2012-06-20 16:38:30 -070011231 ENTER();
11232
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011233 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11234 __func__, hdd_device_modetoString(pAdapter->device_mode),
11235 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011236
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011237 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011238 if (0 != status)
11239 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011240 return status;
11241 }
11242
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011243 if (NULL == pwextBuf)
11244 {
11245 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
11246 __func__);
11247 return -EIO;
11248 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011249 cfg_param = pHddCtx->cfg_ini;
11250 pScanInfo = &pHddCtx->scan_info;
11251
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011252 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11253 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
11254 {
11255 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
11256 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
11257 }
11258
Jeff Johnson295189b2012-06-20 16:38:30 -070011259#ifdef WLAN_BTAMP_FEATURE
11260 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011261 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070011262 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011263 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011264 "%s: No scanning when AMP is on", __func__);
11265 return -EOPNOTSUPP;
11266 }
11267#endif
11268 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011269 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011270 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011271 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011272 "%s: Not scanning on device_mode = %s (%d)",
11273 __func__, hdd_device_modetoString(pAdapter->device_mode),
11274 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011275 return -EOPNOTSUPP;
11276 }
11277
11278 if (TRUE == pScanInfo->mScanPending)
11279 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053011280 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
11281 {
11282 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
11283 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011284 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070011285 }
11286
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053011287 // Don't allow scan if PNO scan is going on.
11288 if (pHddCtx->isPnoEnable)
11289 {
11290 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11291 FL("pno scan in progress"));
11292 return -EBUSY;
11293 }
11294
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011295 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070011296 //Channel and action frame is pending
11297 //Otherwise Cancel Remain On Channel and allow Scan
11298 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011299 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070011300 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053011301 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011302 return -EBUSY;
11303 }
11304
Jeff Johnson295189b2012-06-20 16:38:30 -070011305 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
11306 {
11307 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080011308 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011309 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011310 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011311 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
11312 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011313 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011314 "%s: MAX TM Level Scan not allowed", __func__);
11315 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011316 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070011317 }
11318 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
11319
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011320 /* Check if scan is allowed at this point of time.
11321 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011322 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011323 {
11324 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
11325 return -EBUSY;
11326 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011327
Jeff Johnson295189b2012-06-20 16:38:30 -070011328 vos_mem_zero( &scanRequest, sizeof(scanRequest));
11329
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011330 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
11331 * Becasue of this, driver is assuming that this is not wildcard scan and so
11332 * is not aging out the scan results.
11333 */
11334 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011335 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011336 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011337 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011338
11339 if ((request->ssids) && (0 < request->n_ssids))
11340 {
11341 tCsrSSIDInfo *SsidInfo;
11342 int j;
11343 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
11344 /* Allocate num_ssid tCsrSSIDInfo structure */
11345 SsidInfo = scanRequest.SSIDs.SSIDList =
11346 ( tCsrSSIDInfo *)vos_mem_malloc(
11347 request->n_ssids*sizeof(tCsrSSIDInfo));
11348
11349 if(NULL == scanRequest.SSIDs.SSIDList)
11350 {
11351 hddLog(VOS_TRACE_LEVEL_ERROR,
11352 "%s: memory alloc failed SSIDInfo buffer", __func__);
11353 return -ENOMEM;
11354 }
11355
11356 /* copy all the ssid's and their length */
11357 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
11358 {
11359 /* get the ssid length */
11360 SsidInfo->SSID.length = request->ssids[j].ssid_len;
11361 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
11362 SsidInfo->SSID.length);
11363 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
11364 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
11365 j, SsidInfo->SSID.ssId);
11366 }
11367 /* set the scan type to active */
11368 scanRequest.scanType = eSIR_ACTIVE_SCAN;
11369 }
11370 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011371 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011372 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11373 TRACE_CODE_HDD_CFG80211_SCAN,
11374 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070011375 /* set the scan type to active */
11376 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070011377 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011378 else
11379 {
11380 /*Set the scan type to default type, in this case it is ACTIVE*/
11381 scanRequest.scanType = pScanInfo->scan_mode;
11382 }
11383 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
11384 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070011385
11386 /* set BSSType to default type */
11387 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
11388
11389 /*TODO: scan the requested channels only*/
11390
11391 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011392 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070011393 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011394 hddLog(VOS_TRACE_LEVEL_WARN,
11395 "No of Scan Channels exceeded limit: %d", request->n_channels);
11396 request->n_channels = MAX_CHANNEL;
11397 }
11398
11399 hddLog(VOS_TRACE_LEVEL_INFO,
11400 "No of Scan Channels: %d", request->n_channels);
11401
11402
11403 if( request->n_channels )
11404 {
11405 char chList [(request->n_channels*5)+1];
11406 int len;
11407 channelList = vos_mem_malloc( request->n_channels );
11408 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053011409 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011410 hddLog(VOS_TRACE_LEVEL_ERROR,
11411 "%s: memory alloc failed channelList", __func__);
11412 status = -ENOMEM;
11413 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053011414 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011415
11416 for( i = 0, len = 0; i < request->n_channels ; i++ )
11417 {
11418 channelList[i] = request->channels[i]->hw_value;
11419 len += snprintf(chList+len, 5, "%d ", channelList[i]);
11420 }
11421
Nirav Shah20ac06f2013-12-12 18:14:06 +053011422 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011423 "Channel-List: %s ", chList);
11424 }
c_hpothu53512302014-04-15 18:49:53 +053011425
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011426 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
11427 scanRequest.ChannelInfo.ChannelList = channelList;
11428
11429 /* set requestType to full scan */
11430 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11431
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011432 /* if there is back to back scan happening in driver with in
11433 * nDeferScanTimeInterval interval driver should defer new scan request
11434 * and should provide last cached scan results instead of new channel list.
11435 * This rule is not applicable if scan is p2p scan.
11436 * This condition will work only in case when last request no of channels
11437 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053011438 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053011439 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011440 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011441
Sushant Kaushik86592172015-04-27 16:35:03 +053011442 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
11443 /* if wps ie is NULL , then only defer scan */
11444 if ( pWpsIe == NULL &&
11445 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053011446 {
11447 if ( pScanInfo->last_scan_timestamp !=0 &&
11448 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
11449 {
11450 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
11451 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
11452 vos_mem_compare(pScanInfo->last_scan_channelList,
11453 channelList, pScanInfo->last_scan_numChannels))
11454 {
11455 hddLog(VOS_TRACE_LEVEL_WARN,
11456 " New and old station scan time differ is less then %u",
11457 pHddCtx->cfg_ini->nDeferScanTimeInterval);
11458
11459 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011460 pAdapter);
11461
Agarwal Ashish57e84372014-12-05 18:26:53 +053011462 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011463 "Return old cached scan as all channels and no of channels are same");
11464
Agarwal Ashish57e84372014-12-05 18:26:53 +053011465 if (0 > ret)
11466 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011467
Agarwal Ashish57e84372014-12-05 18:26:53 +053011468 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011469
11470 status = eHAL_STATUS_SUCCESS;
11471 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053011472 }
11473 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011474 }
11475
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011476 /* Flush the scan results(only p2p beacons) for STA scan and P2P
11477 * search (Flush on both full scan and social scan but not on single
11478 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
11479 */
11480
11481 /* Supplicant does single channel scan after 8-way handshake
11482 * and in that case driver shoudnt flush scan results. If
11483 * driver flushes the scan results here and unfortunately if
11484 * the AP doesnt respond to our probe req then association
11485 * fails which is not desired
11486 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011487 if ((request->n_ssids == 1)
11488 && (request->ssids != NULL)
11489 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
11490 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011491
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011492 if( is_p2p_scan ||
11493 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011494 {
11495 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
11496 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
11497 pAdapter->sessionId );
11498 }
11499
11500 if( request->ie_len )
11501 {
11502 /* save this for future association (join requires this) */
11503 /*TODO: Array needs to be converted to dynamic allocation,
11504 * as multiple ie.s can be sent in cfg80211_scan_request structure
11505 * CR 597966
11506 */
11507 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
11508 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
11509 pScanInfo->scanAddIE.length = request->ie_len;
11510
11511 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11512 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11513 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011514 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011515 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070011516 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011517 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
11518 memcpy( pwextBuf->roamProfile.addIEScan,
11519 request->ie, request->ie_len);
11520 }
11521 else
11522 {
11523 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
11524 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011525 }
11526
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011527 }
11528 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
11529 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
11530
11531 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
11532 request->ie_len);
11533 if (pP2pIe != NULL)
11534 {
11535#ifdef WLAN_FEATURE_P2P_DEBUG
11536 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
11537 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
11538 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053011539 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011540 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
11541 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11542 "Go nego completed to Connection is started");
11543 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11544 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053011545 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011546 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
11547 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011548 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011549 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
11550 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11551 "Disconnected state to Connection is started");
11552 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11553 "for 4way Handshake");
11554 }
11555#endif
11556
11557 /* no_cck will be set during p2p find to disable 11b rates */
11558 if(TRUE == request->no_cck)
11559 {
11560 hddLog(VOS_TRACE_LEVEL_INFO,
11561 "%s: This is a P2P Search", __func__);
11562 scanRequest.p2pSearch = 1;
11563
11564 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053011565 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011566 /* set requestType to P2P Discovery */
11567 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
11568 }
11569
11570 /*
11571 Skip Dfs Channel in case of P2P Search
11572 if it is set in ini file
11573 */
11574 if(cfg_param->skipDfsChnlInP2pSearch)
11575 {
11576 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011577 }
11578 else
11579 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011580 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011581 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011582
Agarwal Ashish4f616132013-12-30 23:32:50 +053011583 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011584 }
11585 }
11586
11587 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
11588
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011589#ifdef FEATURE_WLAN_TDLS
11590 /* if tdls disagree scan right now, return immediately.
11591 tdls will schedule the scan when scan is allowed. (return SUCCESS)
11592 or will reject the scan if any TDLS is in progress. (return -EBUSY)
11593 */
11594 status = wlan_hdd_tdls_scan_callback (pAdapter,
11595 wiphy,
11596#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11597 dev,
11598#endif
11599 request);
11600 if(status <= 0)
11601 {
11602 if(!status)
11603 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
11604 "scan rejected %d", __func__, status);
11605 else
11606 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
11607 __func__, status);
11608
11609 return status;
11610 }
11611#endif
11612
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011613 /* acquire the wakelock to avoid the apps suspend during the scan. To
11614 * address the following issues.
11615 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
11616 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
11617 * for long time, this result in apps running at full power for long time.
11618 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
11619 * be stuck in full power because of resume BMPS
11620 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011621 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011622
Nirav Shah20ac06f2013-12-12 18:14:06 +053011623 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11624 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011625 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
11626 scanRequest.requestType, scanRequest.scanType,
11627 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053011628 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
11629
Siddharth Bhal76972212014-10-15 16:22:51 +053011630 if (pHddCtx->spoofMacAddr.isEnabled)
11631 {
11632 hddLog(VOS_TRACE_LEVEL_INFO,
11633 "%s: MAC Spoofing enabled for current scan", __func__);
11634 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
11635 * to fill TxBds for probe request during current scan
11636 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011637 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053011638 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011639
11640 if(status != VOS_STATUS_SUCCESS)
11641 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011642 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011643 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053011644#ifdef FEATURE_WLAN_TDLS
11645 wlan_hdd_tdls_scan_done_callback(pAdapter);
11646#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011647 goto free_mem;
11648 }
Siddharth Bhal76972212014-10-15 16:22:51 +053011649 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053011650 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070011651 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011652 pAdapter->sessionId, &scanRequest, &scanId,
11653 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070011654
Jeff Johnson295189b2012-06-20 16:38:30 -070011655 if (eHAL_STATUS_SUCCESS != status)
11656 {
11657 hddLog(VOS_TRACE_LEVEL_ERROR,
11658 "%s: sme_ScanRequest returned error %d", __func__, status);
11659 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011660 if(eHAL_STATUS_RESOURCES == status)
11661 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011662 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
11663 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011664 status = -EBUSY;
11665 } else {
11666 status = -EIO;
11667 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011668 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011669
11670#ifdef FEATURE_WLAN_TDLS
11671 wlan_hdd_tdls_scan_done_callback(pAdapter);
11672#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011673 goto free_mem;
11674 }
11675
11676 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011677 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011678 pAdapter->request = request;
11679 pScanInfo->scanId = scanId;
11680
11681 complete(&pScanInfo->scan_req_completion_event);
11682
11683free_mem:
11684 if( scanRequest.SSIDs.SSIDList )
11685 {
11686 vos_mem_free(scanRequest.SSIDs.SSIDList);
11687 }
11688
11689 if( channelList )
11690 vos_mem_free( channelList );
11691
11692 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011693 return status;
11694}
11695
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011696int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
11697#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11698 struct net_device *dev,
11699#endif
11700 struct cfg80211_scan_request *request)
11701{
11702 int ret;
11703
11704 vos_ssr_protect(__func__);
11705 ret = __wlan_hdd_cfg80211_scan(wiphy,
11706#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11707 dev,
11708#endif
11709 request);
11710 vos_ssr_unprotect(__func__);
11711
11712 return ret;
11713}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011714
11715void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
11716{
11717 v_U8_t iniDot11Mode =
11718 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
11719 eHddDot11Mode hddDot11Mode = iniDot11Mode;
11720
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011721 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
11722 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011723 switch ( iniDot11Mode )
11724 {
11725 case eHDD_DOT11_MODE_AUTO:
11726 case eHDD_DOT11_MODE_11ac:
11727 case eHDD_DOT11_MODE_11ac_ONLY:
11728#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053011729 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
11730 sme_IsFeatureSupportedByFW(DOT11AC) )
11731 hddDot11Mode = eHDD_DOT11_MODE_11ac;
11732 else
11733 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011734#else
11735 hddDot11Mode = eHDD_DOT11_MODE_11n;
11736#endif
11737 break;
11738 case eHDD_DOT11_MODE_11n:
11739 case eHDD_DOT11_MODE_11n_ONLY:
11740 hddDot11Mode = eHDD_DOT11_MODE_11n;
11741 break;
11742 default:
11743 hddDot11Mode = iniDot11Mode;
11744 break;
11745 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011746#ifdef WLAN_FEATURE_AP_HT40_24G
11747 if (operationChannel > SIR_11B_CHANNEL_END)
11748#endif
11749 {
11750 /* This call decides required channel bonding mode */
11751 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011752 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
11753 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011754 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011755}
11756
Jeff Johnson295189b2012-06-20 16:38:30 -070011757/*
11758 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011759 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011760 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011761int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011762 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070011763{
11764 int status = 0;
11765 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080011766 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011767 v_U32_t roamId;
11768 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070011769 eCsrAuthType RSNAuthType;
11770
11771 ENTER();
11772
11773 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080011774 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11775
11776 status = wlan_hdd_validate_context(pHddCtx);
11777 if (status)
11778 {
Yue Mae36e3552014-03-05 17:06:20 -080011779 return status;
11780 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011781
Jeff Johnson295189b2012-06-20 16:38:30 -070011782 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
11783 {
11784 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
11785 return -EINVAL;
11786 }
11787
11788 pRoamProfile = &pWextState->roamProfile;
11789
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011790 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070011791 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011792 hdd_station_ctx_t *pHddStaCtx;
11793 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011794
Siddharth Bhalda0d1622015-04-24 15:47:49 +053011795 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
11796
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011797 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070011798 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
11799 {
11800 /*QoS not enabled in cfg file*/
11801 pRoamProfile->uapsd_mask = 0;
11802 }
11803 else
11804 {
11805 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011806 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070011807 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
11808 }
11809
11810 pRoamProfile->SSIDs.numOfSSIDs = 1;
11811 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
11812 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011813 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070011814 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
11815 ssid, ssid_len);
11816
11817 if (bssid)
11818 {
11819 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
11820 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
11821 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011822 /* Save BSSID in seperate variable as well, as RoamProfile
11823 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070011824 case of join failure we should send valid BSSID to supplicant
11825 */
11826 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
11827 WNI_CFG_BSSID_LEN);
11828 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070011829 else
11830 {
11831 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
11832 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011833
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011834 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
11835 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011836 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
11837 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011838 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011839 /*set gen ie*/
11840 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
11841 /*set auth*/
11842 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
11843 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011844#ifdef FEATURE_WLAN_WAPI
11845 if (pAdapter->wapi_info.nWapiMode)
11846 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011847 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011848 switch (pAdapter->wapi_info.wapiAuthMode)
11849 {
11850 case WAPI_AUTH_MODE_PSK:
11851 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011852 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011853 pAdapter->wapi_info.wapiAuthMode);
11854 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
11855 break;
11856 }
11857 case WAPI_AUTH_MODE_CERT:
11858 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011859 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011860 pAdapter->wapi_info.wapiAuthMode);
11861 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
11862 break;
11863 }
11864 } // End of switch
11865 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
11866 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
11867 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011868 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011869 pRoamProfile->AuthType.numEntries = 1;
11870 pRoamProfile->EncryptionType.numEntries = 1;
11871 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11872 pRoamProfile->mcEncryptionType.numEntries = 1;
11873 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11874 }
11875 }
11876#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011877#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011878 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011879 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11880 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
11881 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011882 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
11883 sizeof (tSirGtkOffloadParams));
11884 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011885 }
11886#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011887 pRoamProfile->csrPersona = pAdapter->device_mode;
11888
Jeff Johnson32d95a32012-09-10 13:15:23 -070011889 if( operatingChannel )
11890 {
11891 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
11892 pRoamProfile->ChannelInfo.numOfChannels = 1;
11893 }
Chet Lanctot186b5732013-03-18 10:26:30 -070011894 else
11895 {
11896 pRoamProfile->ChannelInfo.ChannelList = NULL;
11897 pRoamProfile->ChannelInfo.numOfChannels = 0;
11898 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011899 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
11900 {
11901 hdd_select_cbmode(pAdapter,operatingChannel);
11902 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011903
Agarwal Ashish40f9b872015-09-01 16:17:35 +053011904 /*
11905 * Change conn_state to connecting before sme_RoamConnect(),
11906 * because sme_RoamConnect() has a direct path to call
11907 * hdd_smeRoamCallback(), which will change the conn_state
11908 * If direct path, conn_state will be accordingly changed
11909 * to NotConnected or Associated by either
11910 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
11911 * in sme_RoamCallback()
11912 * if sme_RomConnect is to be queued,
11913 * Connecting state will remain until it is completed.
11914 * If connection state is not changed,
11915 * connection state will remain in eConnectionState_NotConnected state.
11916 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
11917 * if conn state is eConnectionState_NotConnected.
11918 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
11919 * informed of connect result indication which is an issue.
11920 */
11921
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011922 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11923 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053011924 {
11925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053011926 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011927 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
11928 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053011929 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011930 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011931 pAdapter->sessionId, pRoamProfile, &roamId);
11932
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011933 if ((eHAL_STATUS_SUCCESS != status) &&
11934 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11935 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011936
11937 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053011938 hddLog(VOS_TRACE_LEVEL_ERROR,
11939 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
11940 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011941 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011942 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011943 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011944 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011945
11946 pRoamProfile->ChannelInfo.ChannelList = NULL;
11947 pRoamProfile->ChannelInfo.numOfChannels = 0;
11948
Jeff Johnson295189b2012-06-20 16:38:30 -070011949 }
11950 else
11951 {
11952 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
11953 return -EINVAL;
11954 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011955 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011956 return status;
11957}
11958
11959/*
11960 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
11961 * This function is used to set the authentication type (OPEN/SHARED).
11962 *
11963 */
11964static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
11965 enum nl80211_auth_type auth_type)
11966{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011967 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011968 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11969
11970 ENTER();
11971
11972 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011973 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070011974 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011975 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011976 hddLog(VOS_TRACE_LEVEL_INFO,
11977 "%s: set authentication type to AUTOSWITCH", __func__);
11978 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
11979 break;
11980
11981 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011982#ifdef WLAN_FEATURE_VOWIFI_11R
11983 case NL80211_AUTHTYPE_FT:
11984#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011985 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011986 "%s: set authentication type to OPEN", __func__);
11987 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11988 break;
11989
11990 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011991 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011992 "%s: set authentication type to SHARED", __func__);
11993 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
11994 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011995#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011996 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011997 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011998 "%s: set authentication type to CCKM WPA", __func__);
11999 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
12000 break;
12001#endif
12002
12003
12004 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012005 hddLog(VOS_TRACE_LEVEL_ERROR,
12006 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012007 auth_type);
12008 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
12009 return -EINVAL;
12010 }
12011
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012012 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012013 pHddStaCtx->conn_info.authType;
12014 return 0;
12015}
12016
12017/*
12018 * FUNCTION: wlan_hdd_set_akm_suite
12019 * This function is used to set the key mgmt type(PSK/8021x).
12020 *
12021 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012022static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012023 u32 key_mgmt
12024 )
12025{
12026 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12027 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053012028 /* Should be in ieee802_11_defs.h */
12029#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
12030#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070012031 /*set key mgmt type*/
12032 switch(key_mgmt)
12033 {
12034 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053012035 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012036#ifdef WLAN_FEATURE_VOWIFI_11R
12037 case WLAN_AKM_SUITE_FT_PSK:
12038#endif
12039 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070012040 __func__);
12041 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
12042 break;
12043
12044 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053012045 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012046#ifdef WLAN_FEATURE_VOWIFI_11R
12047 case WLAN_AKM_SUITE_FT_8021X:
12048#endif
12049 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070012050 __func__);
12051 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
12052 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012053#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012054#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
12055#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
12056 case WLAN_AKM_SUITE_CCKM:
12057 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
12058 __func__);
12059 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
12060 break;
12061#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070012062#ifndef WLAN_AKM_SUITE_OSEN
12063#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
12064 case WLAN_AKM_SUITE_OSEN:
12065 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
12066 __func__);
12067 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
12068 break;
12069#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012070
12071 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012072 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012073 __func__, key_mgmt);
12074 return -EINVAL;
12075
12076 }
12077 return 0;
12078}
12079
12080/*
12081 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012082 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070012083 * (NONE/WEP40/WEP104/TKIP/CCMP).
12084 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012085static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
12086 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070012087 bool ucast
12088 )
12089{
12090 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012091 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012092 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12093
12094 ENTER();
12095
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012096 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012097 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012098 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070012099 __func__, cipher);
12100 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12101 }
12102 else
12103 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012104
Jeff Johnson295189b2012-06-20 16:38:30 -070012105 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012106 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012107 {
12108 case IW_AUTH_CIPHER_NONE:
12109 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12110 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012111
Jeff Johnson295189b2012-06-20 16:38:30 -070012112 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012113 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070012114 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012115
Jeff Johnson295189b2012-06-20 16:38:30 -070012116 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012117 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070012118 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012119
Jeff Johnson295189b2012-06-20 16:38:30 -070012120 case WLAN_CIPHER_SUITE_TKIP:
12121 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
12122 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012123
Jeff Johnson295189b2012-06-20 16:38:30 -070012124 case WLAN_CIPHER_SUITE_CCMP:
12125 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12126 break;
12127#ifdef FEATURE_WLAN_WAPI
12128 case WLAN_CIPHER_SUITE_SMS4:
12129 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
12130 break;
12131#endif
12132
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012133#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012134 case WLAN_CIPHER_SUITE_KRK:
12135 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
12136 break;
12137#endif
12138 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012139 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012140 __func__, cipher);
12141 return -EOPNOTSUPP;
12142 }
12143 }
12144
12145 if (ucast)
12146 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012147 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012148 __func__, encryptionType);
12149 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12150 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012151 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012152 encryptionType;
12153 }
12154 else
12155 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012156 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012157 __func__, encryptionType);
12158 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
12159 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
12160 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
12161 }
12162
12163 return 0;
12164}
12165
12166
12167/*
12168 * FUNCTION: wlan_hdd_cfg80211_set_ie
12169 * This function is used to parse WPA/RSN IE's.
12170 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012171int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012172#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12173 const u8 *ie,
12174#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012175 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012176#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012177 size_t ie_len
12178 )
12179{
12180 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012181#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12182 const u8 *genie = ie;
12183#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012184 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012185#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012186 v_U16_t remLen = ie_len;
12187#ifdef FEATURE_WLAN_WAPI
12188 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
12189 u16 *tmp;
12190 v_U16_t akmsuiteCount;
12191 int *akmlist;
12192#endif
12193 ENTER();
12194
12195 /* clear previous assocAddIE */
12196 pWextState->assocAddIE.length = 0;
12197 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012198 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012199
12200 while (remLen >= 2)
12201 {
12202 v_U16_t eLen = 0;
12203 v_U8_t elementId;
12204 elementId = *genie++;
12205 eLen = *genie++;
12206 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012207
Arif Hussain6d2a3322013-11-17 19:50:10 -080012208 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070012209 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012210
12211 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070012212 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012213 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012214 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 -070012215 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012216 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012217 "%s: Invalid WPA IE", __func__);
12218 return -EINVAL;
12219 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012220 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070012221 {
12222 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012223 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012224 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012225
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012226 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012227 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012228 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
12229 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012230 VOS_ASSERT(0);
12231 return -ENOMEM;
12232 }
12233 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12234 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12235 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012236
Jeff Johnson295189b2012-06-20 16:38:30 -070012237 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
12238 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12239 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12240 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012241 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
12242 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012243 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
12244 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12245 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
12246 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
12247 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
12248 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012249 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053012250 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070012251 {
12252 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012253 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012254 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012255
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012256 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012257 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012258 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12259 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012260 VOS_ASSERT(0);
12261 return -ENOMEM;
12262 }
12263 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12264 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12265 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012266
Jeff Johnson295189b2012-06-20 16:38:30 -070012267 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12268 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12269 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012270#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012271 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
12272 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012273 /*Consider WFD IE, only for P2P Client */
12274 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
12275 {
12276 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012277 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012278 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012279
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012280 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012281 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012282 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12283 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012284 VOS_ASSERT(0);
12285 return -ENOMEM;
12286 }
12287 // WFD IE is saved to Additional IE ; it should be accumulated to handle
12288 // WPS IE + P2P IE + WFD IE
12289 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12290 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012291
Jeff Johnson295189b2012-06-20 16:38:30 -070012292 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12293 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12294 }
12295#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012296 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012297 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012298 HS20_OUI_TYPE_SIZE)) )
12299 {
12300 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012301 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012302 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012303
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012304 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012305 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012306 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12307 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012308 VOS_ASSERT(0);
12309 return -ENOMEM;
12310 }
12311 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12312 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012313
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012314 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12315 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12316 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012317 /* Appending OSEN Information Element in Assiciation Request */
12318 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
12319 OSEN_OUI_TYPE_SIZE)) )
12320 {
12321 v_U16_t curAddIELen = pWextState->assocAddIE.length;
12322 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
12323 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012324
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012325 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012326 {
12327 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12328 "Need bigger buffer space");
12329 VOS_ASSERT(0);
12330 return -ENOMEM;
12331 }
12332 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12333 pWextState->assocAddIE.length += eLen + 2;
12334
12335 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
12336 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12337 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12338 }
12339
Abhishek Singh4322e622015-06-10 15:42:54 +053012340 /* Update only for WPA IE */
12341 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
12342 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012343
12344 /* populating as ADDIE in beacon frames */
12345 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012346 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012347 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
12348 {
12349 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12350 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
12351 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12352 {
12353 hddLog(LOGE,
12354 "Coldn't pass "
12355 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
12356 }
12357 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
12358 else
12359 hddLog(LOGE,
12360 "Could not pass on "
12361 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
12362
12363 /* IBSS mode doesn't contain params->proberesp_ies still
12364 beaconIE's need to be populated in probe response frames */
12365 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
12366 {
12367 u16 rem_probe_resp_ie_len = eLen + 2;
12368 u8 probe_rsp_ie_len[3] = {0};
12369 u8 counter = 0;
12370
12371 /* Check Probe Resp Length if it is greater then 255 then
12372 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
12373 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
12374 not able Store More then 255 bytes into One Variable */
12375
12376 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
12377 {
12378 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
12379 {
12380 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
12381 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
12382 }
12383 else
12384 {
12385 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
12386 rem_probe_resp_ie_len = 0;
12387 }
12388 }
12389
12390 rem_probe_resp_ie_len = 0;
12391
12392 if (probe_rsp_ie_len[0] > 0)
12393 {
12394 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12395 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
12396 (tANI_U8*)(genie - 2),
12397 probe_rsp_ie_len[0], NULL,
12398 eANI_BOOLEAN_FALSE)
12399 == eHAL_STATUS_FAILURE)
12400 {
12401 hddLog(LOGE,
12402 "Could not pass"
12403 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
12404 }
12405 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
12406 }
12407
12408 if (probe_rsp_ie_len[1] > 0)
12409 {
12410 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12411 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
12412 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12413 probe_rsp_ie_len[1], NULL,
12414 eANI_BOOLEAN_FALSE)
12415 == eHAL_STATUS_FAILURE)
12416 {
12417 hddLog(LOGE,
12418 "Could not pass"
12419 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
12420 }
12421 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
12422 }
12423
12424 if (probe_rsp_ie_len[2] > 0)
12425 {
12426 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12427 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
12428 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12429 probe_rsp_ie_len[2], NULL,
12430 eANI_BOOLEAN_FALSE)
12431 == eHAL_STATUS_FAILURE)
12432 {
12433 hddLog(LOGE,
12434 "Could not pass"
12435 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
12436 }
12437 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
12438 }
12439
12440 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12441 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
12442 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12443 {
12444 hddLog(LOGE,
12445 "Could not pass"
12446 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
12447 }
12448 }
12449 else
12450 {
12451 // Reset WNI_CFG_PROBE_RSP Flags
12452 wlan_hdd_reset_prob_rspies(pAdapter);
12453
12454 hddLog(VOS_TRACE_LEVEL_INFO,
12455 "%s: No Probe Response IE received in set beacon",
12456 __func__);
12457 }
12458 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012459 break;
12460 case DOT11F_EID_RSN:
12461 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
12462 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12463 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
12464 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
12465 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
12466 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053012467
12468 /* Appending Extended Capabilities with Interworking bit set
12469 * in Assoc Req.
12470 *
12471 * In assoc req this EXT Cap will only be taken into account if
12472 * interworkingService bit is set to 1. Currently
12473 * driver is only interested in interworkingService capability
12474 * from supplicant. If in future any other EXT Cap info is
12475 * required from supplicat, it needs to be handled while
12476 * sending Assoc Req in LIM.
12477 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012478 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012479 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012480 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012481 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012482 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012483
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012484 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012485 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012486 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12487 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012488 VOS_ASSERT(0);
12489 return -ENOMEM;
12490 }
12491 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12492 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012493
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012494 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12495 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12496 break;
12497 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012498#ifdef FEATURE_WLAN_WAPI
12499 case WLAN_EID_WAPI:
12500 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012501 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012502 pAdapter->wapi_info.nWapiMode);
12503 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012504 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070012505 akmsuiteCount = WPA_GET_LE16(tmp);
12506 tmp = tmp + 1;
12507 akmlist = (int *)(tmp);
12508 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
12509 {
12510 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
12511 }
12512 else
12513 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012514 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070012515 VOS_ASSERT(0);
12516 return -EINVAL;
12517 }
12518
12519 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
12520 {
12521 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012522 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012523 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012524 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012525 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012526 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012527 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012528 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012529 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
12530 }
12531 break;
12532#endif
12533 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012534 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012535 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012536 /* when Unknown IE is received we should break and continue
12537 * to the next IE in the buffer instead we were returning
12538 * so changing this to break */
12539 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070012540 }
12541 genie += eLen;
12542 remLen -= eLen;
12543 }
12544 EXIT();
12545 return 0;
12546}
12547
12548/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012549 * FUNCTION: hdd_isWPAIEPresent
12550 * Parse the received IE to find the WPA IE
12551 *
12552 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012553static bool hdd_isWPAIEPresent(
12554#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
12555 const u8 *ie,
12556#else
12557 u8 *ie,
12558#endif
12559 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012560{
12561 v_U8_t eLen = 0;
12562 v_U16_t remLen = ie_len;
12563 v_U8_t elementId = 0;
12564
12565 while (remLen >= 2)
12566 {
12567 elementId = *ie++;
12568 eLen = *ie++;
12569 remLen -= 2;
12570 if (eLen > remLen)
12571 {
12572 hddLog(VOS_TRACE_LEVEL_ERROR,
12573 "%s: IE length is wrong %d", __func__, eLen);
12574 return FALSE;
12575 }
12576 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
12577 {
12578 /* OUI - 0x00 0X50 0XF2
12579 WPA Information Element - 0x01
12580 WPA version - 0x01*/
12581 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
12582 return TRUE;
12583 }
12584 ie += eLen;
12585 remLen -= eLen;
12586 }
12587 return FALSE;
12588}
12589
12590/*
Jeff Johnson295189b2012-06-20 16:38:30 -070012591 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012592 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012593 * parameters during connect operation.
12594 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012595int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012596 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012597 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012598{
12599 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012600 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012601 ENTER();
12602
12603 /*set wpa version*/
12604 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
12605
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012606 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012607 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053012608 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012609 {
12610 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12611 }
12612 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
12613 {
12614 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12615 }
12616 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012617
12618 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012619 pWextState->wpaVersion);
12620
12621 /*set authentication type*/
12622 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
12623
12624 if (0 > status)
12625 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012626 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012627 "%s: failed to set authentication type ", __func__);
12628 return status;
12629 }
12630
12631 /*set key mgmt type*/
12632 if (req->crypto.n_akm_suites)
12633 {
12634 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
12635 if (0 > status)
12636 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012637 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070012638 __func__);
12639 return status;
12640 }
12641 }
12642
12643 /*set pairwise cipher type*/
12644 if (req->crypto.n_ciphers_pairwise)
12645 {
12646 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
12647 req->crypto.ciphers_pairwise[0], true);
12648 if (0 > status)
12649 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012650 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012651 "%s: failed to set unicast cipher type", __func__);
12652 return status;
12653 }
12654 }
12655 else
12656 {
12657 /*Reset previous cipher suite to none*/
12658 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
12659 if (0 > status)
12660 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012661 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012662 "%s: failed to set unicast cipher type", __func__);
12663 return status;
12664 }
12665 }
12666
12667 /*set group cipher type*/
12668 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
12669 false);
12670
12671 if (0 > status)
12672 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012673 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070012674 __func__);
12675 return status;
12676 }
12677
Chet Lanctot186b5732013-03-18 10:26:30 -070012678#ifdef WLAN_FEATURE_11W
12679 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
12680#endif
12681
Jeff Johnson295189b2012-06-20 16:38:30 -070012682 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
12683 if (req->ie_len)
12684 {
12685 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
12686 if ( 0 > status)
12687 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012688 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012689 __func__);
12690 return status;
12691 }
12692 }
12693
12694 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012695 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012696 {
12697 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
12698 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
12699 )
12700 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012701 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070012702 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
12703 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012704 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012705 __func__);
12706 return -EOPNOTSUPP;
12707 }
12708 else
12709 {
12710 u8 key_len = req->key_len;
12711 u8 key_idx = req->key_idx;
12712
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012713 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012714 && (CSR_MAX_NUM_KEY > key_idx)
12715 )
12716 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012717 hddLog(VOS_TRACE_LEVEL_INFO,
12718 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012719 __func__, key_idx, key_len);
12720 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012721 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012722 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012723 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012724 (u8)key_len;
12725 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
12726 }
12727 }
12728 }
12729 }
12730
12731 return status;
12732}
12733
12734/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012735 * FUNCTION: wlan_hdd_try_disconnect
12736 * This function is used to disconnect from previous
12737 * connection
12738 */
12739static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
12740{
12741 long ret = 0;
12742 hdd_station_ctx_t *pHddStaCtx;
12743 eMib_dot11DesiredBssType connectedBssType;
12744
12745 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12746
12747 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
12748
12749 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
12750 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
12751 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
12752 {
12753 /* Issue disconnect to CSR */
12754 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12755 if( eHAL_STATUS_SUCCESS ==
12756 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12757 pAdapter->sessionId,
12758 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12759 {
12760 ret = wait_for_completion_interruptible_timeout(
12761 &pAdapter->disconnect_comp_var,
12762 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12763 if (0 >= ret)
12764 {
12765 hddLog(LOGE, FL("Failed to receive disconnect event"));
12766 return -EALREADY;
12767 }
12768 }
12769 }
12770 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
12771 {
12772 ret = wait_for_completion_interruptible_timeout(
12773 &pAdapter->disconnect_comp_var,
12774 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12775 if (0 >= ret)
12776 {
12777 hddLog(LOGE, FL("Failed to receive disconnect event"));
12778 return -EALREADY;
12779 }
12780 }
12781
12782 return 0;
12783}
12784
12785/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053012786 * FUNCTION: __wlan_hdd_cfg80211_connect
12787 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012788 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012789static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012790 struct net_device *ndev,
12791 struct cfg80211_connect_params *req
12792 )
12793{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012794 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012795 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012796 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053012797 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012798
12799 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012800
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012801 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12802 TRACE_CODE_HDD_CFG80211_CONNECT,
12803 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012804 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012805 "%s: device_mode = %s (%d)", __func__,
12806 hdd_device_modetoString(pAdapter->device_mode),
12807 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012808
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012809 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012810 if (!pHddCtx)
12811 {
12812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12813 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053012814 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012815 }
12816
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012817 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012818 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012819 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012820 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012821 }
12822
Agarwal Ashish51325b52014-06-16 16:50:49 +053012823 if (vos_max_concurrent_connections_reached()) {
12824 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12825 return -ECONNREFUSED;
12826 }
12827
Jeff Johnson295189b2012-06-20 16:38:30 -070012828#ifdef WLAN_BTAMP_FEATURE
12829 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012830 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070012831 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012832 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012833 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012834 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070012835 }
12836#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012837
12838 //If Device Mode is Station Concurrent Sessions Exit BMps
12839 //P2P Mode will be taken care in Open/close adapter
12840 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012841 (vos_concurrent_open_sessions_running())) {
12842 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
12843 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012844 }
12845
12846 /*Try disconnecting if already in connected state*/
12847 status = wlan_hdd_try_disconnect(pAdapter);
12848 if ( 0 > status)
12849 {
12850 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12851 " connection"));
12852 return -EALREADY;
12853 }
12854
Jeff Johnson295189b2012-06-20 16:38:30 -070012855 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012856 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070012857
12858 if ( 0 > status)
12859 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012860 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070012861 __func__);
12862 return status;
12863 }
Mohit Khanna765234a2012-09-11 15:08:35 -070012864 if ( req->channel )
12865 {
12866 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
12867 req->ssid_len, req->bssid,
12868 req->channel->hw_value);
12869 }
12870 else
12871 {
12872 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012873 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070012874 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012875
Sushant Kaushikd7083982015-03-18 14:33:24 +053012876 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012877 {
12878 //ReEnable BMPS if disabled
12879 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
12880 (NULL != pHddCtx))
12881 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012882 if (pHddCtx->hdd_wlan_suspended)
12883 {
12884 hdd_set_pwrparams(pHddCtx);
12885 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012886 //ReEnable Bmps and Imps back
12887 hdd_enable_bmps_imps(pHddCtx);
12888 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053012889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070012890 return status;
12891 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012892 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012893 EXIT();
12894 return status;
12895}
12896
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012897static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
12898 struct net_device *ndev,
12899 struct cfg80211_connect_params *req)
12900{
12901 int ret;
12902 vos_ssr_protect(__func__);
12903 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
12904 vos_ssr_unprotect(__func__);
12905
12906 return ret;
12907}
Jeff Johnson295189b2012-06-20 16:38:30 -070012908
12909/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012910 * FUNCTION: wlan_hdd_disconnect
12911 * This function is used to issue a disconnect request to SME
12912 */
12913int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
12914{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012915 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012916 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012917 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012918 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012919
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012920 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012921
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012922 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012923 if (0 != status)
12924 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012925 return status;
12926 }
12927
Sushant Kaushikb4834d22015-07-15 15:29:05 +053012928 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
12929 {
12930 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
12931 pAdapter->sessionId);
12932 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012933 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012934
Agarwal Ashish47d18112014-08-04 19:55:07 +053012935 /* Need to apply spin lock before decreasing active sessions
12936 * as there can be chance for double decrement if context switch
12937 * Calls hdd_DisConnectHandler.
12938 */
12939
12940 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012941 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
12942 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012943 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
12944 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053012945 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
12946 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012947
Abhishek Singhf4669da2014-05-26 15:07:49 +053012948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053012949 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
12950
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012951 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012952
Mihir Shete182a0b22014-08-18 16:08:48 +053012953 /*
12954 * stop tx queues before deleting STA/BSS context from the firmware.
12955 * tx has to be disabled because the firmware can get busy dropping
12956 * the tx frames after BSS/STA has been deleted and will not send
12957 * back a response resulting in WDI timeout
12958 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053012959 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053012960 netif_tx_disable(pAdapter->dev);
12961 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012962
Mihir Shete182a0b22014-08-18 16:08:48 +053012963 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012964 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12965 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012966 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
12967 {
12968 hddLog(VOS_TRACE_LEVEL_INFO,
12969 FL("status = %d, already disconnected"),
12970 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012971
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012972 }
12973 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012974 {
12975 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012976 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012977 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012978 result = -EINVAL;
12979 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012980 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012981 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012982 &pAdapter->disconnect_comp_var,
12983 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012984 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012985 {
12986 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012987 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012988 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012989 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012990 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012991 {
12992 hddLog(VOS_TRACE_LEVEL_ERROR,
12993 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012994 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012995 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012996disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12998 FL("Set HDD connState to eConnectionState_NotConnected"));
12999 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
13000
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013001 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013002 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013003}
13004
13005
13006/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013007 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070013008 * This function is used to issue a disconnect request to SME
13009 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013010static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013011 struct net_device *dev,
13012 u16 reason
13013 )
13014{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013015 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013016 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013017 tCsrRoamProfile *pRoamProfile;
13018 hdd_station_ctx_t *pHddStaCtx;
13019 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013020#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013021 tANI_U8 staIdx;
13022#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013023
Jeff Johnson295189b2012-06-20 16:38:30 -070013024 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013025
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013026 if (!pAdapter) {
13027 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
13028 return -EINVAL;
13029 }
13030
13031 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13032 if (!pHddStaCtx) {
13033 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
13034 return -EINVAL;
13035 }
13036
13037 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13038 status = wlan_hdd_validate_context(pHddCtx);
13039 if (0 != status)
13040 {
13041 return status;
13042 }
13043
13044 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
13045
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013046 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13047 TRACE_CODE_HDD_CFG80211_DISCONNECT,
13048 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013049 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
13050 __func__, hdd_device_modetoString(pAdapter->device_mode),
13051 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013052
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013053 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
13054 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070013055
Jeff Johnson295189b2012-06-20 16:38:30 -070013056 if (NULL != pRoamProfile)
13057 {
13058 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053013059 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
13060 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070013061 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013062 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070013063 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013064 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013065 switch(reason)
13066 {
13067 case WLAN_REASON_MIC_FAILURE:
13068 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
13069 break;
13070
13071 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
13072 case WLAN_REASON_DISASSOC_AP_BUSY:
13073 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
13074 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
13075 break;
13076
13077 case WLAN_REASON_PREV_AUTH_NOT_VALID:
13078 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053013079 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070013080 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
13081 break;
13082
Jeff Johnson295189b2012-06-20 16:38:30 -070013083 default:
13084 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
13085 break;
13086 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013087 pScanInfo = &pHddCtx->scan_info;
13088 if (pScanInfo->mScanPending)
13089 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053013090 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013091 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013092 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053013093 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013094 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053013095 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013096#ifdef FEATURE_WLAN_TDLS
13097 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013098 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013099 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013100 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
13101 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013102 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013103 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013104 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053013105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013106 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013107 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013108 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053013109 status = sme_DeleteTdlsPeerSta(
13110 WLAN_HDD_GET_HAL_CTX(pAdapter),
13111 pAdapter->sessionId,
13112 mac);
13113 if (status != eHAL_STATUS_SUCCESS) {
13114 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
13115 return -EPERM;
13116 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013117 }
13118 }
13119#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013120 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013121 status = wlan_hdd_disconnect(pAdapter, reasonCode);
13122 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070013123 {
13124 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013125 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013126 __func__, (int)status );
13127 return -EINVAL;
13128 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013129 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053013130 else
13131 {
13132 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
13133 "called while in %d state", __func__,
13134 pHddStaCtx->conn_info.connState);
13135 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013136 }
13137 else
13138 {
13139 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
13140 }
13141
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013142 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013143 return status;
13144}
13145
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013146static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
13147 struct net_device *dev,
13148 u16 reason
13149 )
13150{
13151 int ret;
13152 vos_ssr_protect(__func__);
13153 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
13154 vos_ssr_unprotect(__func__);
13155
13156 return ret;
13157}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013158
Jeff Johnson295189b2012-06-20 16:38:30 -070013159/*
13160 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013161 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070013162 * settings in IBSS mode.
13163 */
13164static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013165 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013166 struct cfg80211_ibss_params *params
13167 )
13168{
13169 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013170 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013171 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13172 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013173
Jeff Johnson295189b2012-06-20 16:38:30 -070013174 ENTER();
13175
13176 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070013177 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070013178
13179 if (params->ie_len && ( NULL != params->ie) )
13180 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013181 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13182 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013183 {
13184 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
13185 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13186 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013187 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013188 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013189 tDot11fIEWPA dot11WPAIE;
13190 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013191 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013192
Wilson Yang00256342013-10-10 23:13:38 -070013193 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013194 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13195 params->ie_len, DOT11F_EID_WPA);
13196 if ( NULL != ie )
13197 {
13198 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
13199 // Unpack the WPA IE
13200 //Skip past the EID byte and length byte - and four byte WiFi OUI
13201 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
13202 &ie[2+4],
13203 ie[1] - 4,
13204 &dot11WPAIE);
13205 /*Extract the multicast cipher, the encType for unicast
13206 cipher for wpa-none is none*/
13207 encryptionType =
13208 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
13209 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013210 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013211
Jeff Johnson295189b2012-06-20 16:38:30 -070013212 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
13213
13214 if (0 > status)
13215 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013216 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070013217 __func__);
13218 return status;
13219 }
13220 }
13221
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013222 pWextState->roamProfile.AuthType.authType[0] =
13223 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013224 eCSR_AUTH_TYPE_OPEN_SYSTEM;
13225
13226 if (params->privacy)
13227 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013228 /* Security enabled IBSS, At this time there is no information available
13229 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070013230 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013231 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070013232 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013233 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070013234 *enable privacy bit in beacons */
13235
13236 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13237 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013238 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
13239 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070013240 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13241 pWextState->roamProfile.EncryptionType.numEntries = 1;
13242 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070013243 return status;
13244}
13245
13246/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013247 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013248 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013249 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013250static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013251 struct net_device *dev,
13252 struct cfg80211_ibss_params *params
13253 )
13254{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013255 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013256 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13257 tCsrRoamProfile *pRoamProfile;
13258 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013259 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13260 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013261 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070013262
13263 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013264
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013265 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13266 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
13267 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013268 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013269 "%s: device_mode = %s (%d)", __func__,
13270 hdd_device_modetoString(pAdapter->device_mode),
13271 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013272
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013273 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013274 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013275 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013276 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013277 }
13278
13279 if (NULL == pWextState)
13280 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013281 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070013282 __func__);
13283 return -EIO;
13284 }
13285
Agarwal Ashish51325b52014-06-16 16:50:49 +053013286 if (vos_max_concurrent_connections_reached()) {
13287 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13288 return -ECONNREFUSED;
13289 }
13290
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013291 /*Try disconnecting if already in connected state*/
13292 status = wlan_hdd_try_disconnect(pAdapter);
13293 if ( 0 > status)
13294 {
13295 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
13296 " IBSS connection"));
13297 return -EALREADY;
13298 }
13299
Jeff Johnson295189b2012-06-20 16:38:30 -070013300 pRoamProfile = &pWextState->roamProfile;
13301
13302 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
13303 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013304 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013305 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013306 return -EINVAL;
13307 }
13308
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013309 /* BSSID is provided by upper layers hence no need to AUTO generate */
13310 if (NULL != params->bssid) {
13311 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
13312 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
13313 hddLog (VOS_TRACE_LEVEL_ERROR,
13314 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
13315 return -EIO;
13316 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013317 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013318 }
krunal sonie9002db2013-11-25 14:24:17 -080013319 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
13320 {
13321 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
13322 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
13323 {
13324 hddLog (VOS_TRACE_LEVEL_ERROR,
13325 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
13326 return -EIO;
13327 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013328
13329 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080013330 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013331 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080013332 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013333
Jeff Johnson295189b2012-06-20 16:38:30 -070013334 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070013335 if (NULL !=
13336#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13337 params->chandef.chan)
13338#else
13339 params->channel)
13340#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013341 {
13342 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013343 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13344 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
13345 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13346 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013347
13348 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013349 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070013350 ieee80211_frequency_to_channel(
13351#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13352 params->chandef.chan->center_freq);
13353#else
13354 params->channel->center_freq);
13355#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013356
13357 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13358 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070013359 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013360 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
13361 __func__);
13362 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070013363 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013364
13365 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013366 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013367 if (channelNum == validChan[indx])
13368 {
13369 break;
13370 }
13371 }
13372 if (indx >= numChans)
13373 {
13374 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013375 __func__, channelNum);
13376 return -EINVAL;
13377 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013378 /* Set the Operational Channel */
13379 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
13380 channelNum);
13381 pRoamProfile->ChannelInfo.numOfChannels = 1;
13382 pHddStaCtx->conn_info.operationChannel = channelNum;
13383 pRoamProfile->ChannelInfo.ChannelList =
13384 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070013385 }
13386
13387 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013388 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070013389 if (status < 0)
13390 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013391 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070013392 __func__);
13393 return status;
13394 }
13395
13396 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013397 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013398 params->ssid_len, params->bssid,
13399 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013400
13401 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013402 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013403
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013404 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013405 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013406}
13407
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013408static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
13409 struct net_device *dev,
13410 struct cfg80211_ibss_params *params
13411 )
13412{
13413 int ret = 0;
13414
13415 vos_ssr_protect(__func__);
13416 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
13417 vos_ssr_unprotect(__func__);
13418
13419 return ret;
13420}
13421
Jeff Johnson295189b2012-06-20 16:38:30 -070013422/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013423 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013424 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013425 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013426static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013427 struct net_device *dev
13428 )
13429{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013430 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013431 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13432 tCsrRoamProfile *pRoamProfile;
13433 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013434 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013435
13436 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013437
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013438 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13439 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
13440 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013441 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013442 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013443 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013444 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013445 }
13446
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013447 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
13448 hdd_device_modetoString(pAdapter->device_mode),
13449 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013450 if (NULL == pWextState)
13451 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013452 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070013453 __func__);
13454 return -EIO;
13455 }
13456
13457 pRoamProfile = &pWextState->roamProfile;
13458
13459 /* Issue disconnect only if interface type is set to IBSS */
13460 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
13461 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013462 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070013463 __func__);
13464 return -EINVAL;
13465 }
13466
13467 /* Issue Disconnect request */
13468 INIT_COMPLETION(pAdapter->disconnect_comp_var);
13469 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13470 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
13471
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013472 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013473 return 0;
13474}
13475
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013476static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
13477 struct net_device *dev
13478 )
13479{
13480 int ret = 0;
13481
13482 vos_ssr_protect(__func__);
13483 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
13484 vos_ssr_unprotect(__func__);
13485
13486 return ret;
13487}
13488
Jeff Johnson295189b2012-06-20 16:38:30 -070013489/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013490 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070013491 * This function is used to set the phy parameters
13492 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
13493 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013494static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013495 u32 changed)
13496{
13497 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13498 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013499 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013500
13501 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013502
13503 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013504 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
13505 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013506
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013507 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013508 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013509 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013510 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013511 }
13512
Jeff Johnson295189b2012-06-20 16:38:30 -070013513 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
13514 {
13515 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
13516 WNI_CFG_RTS_THRESHOLD_STAMAX :
13517 wiphy->rts_threshold;
13518
13519 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013520 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070013521 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013522 hddLog(VOS_TRACE_LEVEL_ERROR,
13523 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013524 __func__, rts_threshold);
13525 return -EINVAL;
13526 }
13527
13528 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
13529 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013530 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013531 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013532 hddLog(VOS_TRACE_LEVEL_ERROR,
13533 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013534 __func__, rts_threshold);
13535 return -EIO;
13536 }
13537
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013538 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013539 rts_threshold);
13540 }
13541
13542 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
13543 {
13544 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
13545 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
13546 wiphy->frag_threshold;
13547
13548 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013549 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013550 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013551 hddLog(VOS_TRACE_LEVEL_ERROR,
13552 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013553 frag_threshold);
13554 return -EINVAL;
13555 }
13556
13557 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
13558 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013559 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013560 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013561 hddLog(VOS_TRACE_LEVEL_ERROR,
13562 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013563 __func__, frag_threshold);
13564 return -EIO;
13565 }
13566
13567 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
13568 frag_threshold);
13569 }
13570
13571 if ((changed & WIPHY_PARAM_RETRY_SHORT)
13572 || (changed & WIPHY_PARAM_RETRY_LONG))
13573 {
13574 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
13575 wiphy->retry_short :
13576 wiphy->retry_long;
13577
13578 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
13579 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
13580 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013581 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013582 __func__, retry_value);
13583 return -EINVAL;
13584 }
13585
13586 if (changed & WIPHY_PARAM_RETRY_SHORT)
13587 {
13588 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
13589 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013590 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013591 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013592 hddLog(VOS_TRACE_LEVEL_ERROR,
13593 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013594 __func__, retry_value);
13595 return -EIO;
13596 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013597 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013598 __func__, retry_value);
13599 }
13600 else if (changed & WIPHY_PARAM_RETRY_SHORT)
13601 {
13602 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
13603 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013604 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013605 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013606 hddLog(VOS_TRACE_LEVEL_ERROR,
13607 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013608 __func__, retry_value);
13609 return -EIO;
13610 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013611 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013612 __func__, retry_value);
13613 }
13614 }
13615
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013616 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013617 return 0;
13618}
13619
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013620static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
13621 u32 changed)
13622{
13623 int ret;
13624
13625 vos_ssr_protect(__func__);
13626 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
13627 vos_ssr_unprotect(__func__);
13628
13629 return ret;
13630}
13631
Jeff Johnson295189b2012-06-20 16:38:30 -070013632/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013633 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013634 * This function is used to set the txpower
13635 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013636static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013637#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13638 struct wireless_dev *wdev,
13639#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013640#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013641 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013642#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013643 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013644#endif
13645 int dbm)
13646{
13647 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013648 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013649 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13650 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013651 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013652
13653 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013654
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013655 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13656 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
13657 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013658 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013659 if (0 != status)
13660 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013661 return status;
13662 }
13663
13664 hHal = pHddCtx->hHal;
13665
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013666 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
13667 dbm, ccmCfgSetCallback,
13668 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013669 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013670 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013671 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
13672 return -EIO;
13673 }
13674
13675 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
13676 dbm);
13677
13678 switch(type)
13679 {
13680 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
13681 /* Fall through */
13682 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
13683 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
13684 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013685 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
13686 __func__);
13687 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013688 }
13689 break;
13690 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013691 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070013692 __func__);
13693 return -EOPNOTSUPP;
13694 break;
13695 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013696 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
13697 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070013698 return -EIO;
13699 }
13700
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013701 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013702 return 0;
13703}
13704
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013705static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
13706#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13707 struct wireless_dev *wdev,
13708#endif
13709#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13710 enum tx_power_setting type,
13711#else
13712 enum nl80211_tx_power_setting type,
13713#endif
13714 int dbm)
13715{
13716 int ret;
13717 vos_ssr_protect(__func__);
13718 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
13719#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13720 wdev,
13721#endif
13722#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13723 type,
13724#else
13725 type,
13726#endif
13727 dbm);
13728 vos_ssr_unprotect(__func__);
13729
13730 return ret;
13731}
13732
Jeff Johnson295189b2012-06-20 16:38:30 -070013733/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013734 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013735 * This function is used to read the txpower
13736 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013737static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013738#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13739 struct wireless_dev *wdev,
13740#endif
13741 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070013742{
13743
13744 hdd_adapter_t *pAdapter;
13745 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013746 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013747
Jeff Johnsone7245742012-09-05 17:12:55 -070013748 ENTER();
13749
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013750 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013751 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013752 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013753 *dbm = 0;
13754 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013755 }
13756
Jeff Johnson295189b2012-06-20 16:38:30 -070013757 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
13758 if (NULL == pAdapter)
13759 {
13760 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
13761 return -ENOENT;
13762 }
13763
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053013764 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13765 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
13766 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013767 wlan_hdd_get_classAstats(pAdapter);
13768 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
13769
Jeff Johnsone7245742012-09-05 17:12:55 -070013770 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013771 return 0;
13772}
13773
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013774static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
13775#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13776 struct wireless_dev *wdev,
13777#endif
13778 int *dbm)
13779{
13780 int ret;
13781
13782 vos_ssr_protect(__func__);
13783 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
13784#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13785 wdev,
13786#endif
13787 dbm);
13788 vos_ssr_unprotect(__func__);
13789
13790 return ret;
13791}
13792
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013793static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013794#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13795 const u8* mac,
13796#else
13797 u8* mac,
13798#endif
13799 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070013800{
13801 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13802 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13803 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053013804 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013805
13806 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
13807 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070013808
13809 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
13810 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
13811 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
13812 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
13813 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
13814 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
13815 tANI_U16 maxRate = 0;
13816 tANI_U16 myRate;
13817 tANI_U16 currentRate = 0;
13818 tANI_U8 maxSpeedMCS = 0;
13819 tANI_U8 maxMCSIdx = 0;
13820 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053013821 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013822 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013823 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013824
Leo Chang6f8870f2013-03-26 18:11:36 -070013825#ifdef WLAN_FEATURE_11AC
13826 tANI_U32 vht_mcs_map;
13827 eDataRate11ACMaxMcs vhtMaxMcs;
13828#endif /* WLAN_FEATURE_11AC */
13829
Jeff Johnsone7245742012-09-05 17:12:55 -070013830 ENTER();
13831
Jeff Johnson295189b2012-06-20 16:38:30 -070013832 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
13833 (0 == ssidlen))
13834 {
13835 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
13836 " Invalid ssidlen, %d", __func__, ssidlen);
13837 /*To keep GUI happy*/
13838 return 0;
13839 }
13840
Mukul Sharma811205f2014-07-09 21:07:30 +053013841 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
13842 {
13843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13844 "%s: Roaming in progress, so unable to proceed this request", __func__);
13845 return 0;
13846 }
13847
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013848 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013849 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013850 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013851 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013852 }
13853
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053013854 wlan_hdd_get_station_stats(pAdapter);
13855 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013856
Kiet Lam3b17fc82013-09-27 05:24:08 +053013857 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
13858 sinfo->filled |= STATION_INFO_SIGNAL;
13859
c_hpothu09f19542014-05-30 21:53:31 +053013860 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053013861 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
13862 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053013863 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053013864 {
13865 rate_flags = pAdapter->maxRateFlags;
13866 }
c_hpothu44ff4e02014-05-08 00:13:57 +053013867
Jeff Johnson295189b2012-06-20 16:38:30 -070013868 //convert to the UI units of 100kbps
13869 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
13870
13871#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070013872 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 -070013873 sinfo->signal,
13874 pCfg->reportMaxLinkSpeed,
13875 myRate,
13876 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013877 (int) pCfg->linkSpeedRssiMid,
13878 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070013879 (int) rate_flags,
13880 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013881#endif //LINKSPEED_DEBUG_ENABLED
13882
13883 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
13884 {
13885 // we do not want to necessarily report the current speed
13886 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
13887 {
13888 // report the max possible speed
13889 rssidx = 0;
13890 }
13891 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
13892 {
13893 // report the max possible speed with RSSI scaling
13894 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
13895 {
13896 // report the max possible speed
13897 rssidx = 0;
13898 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013899 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070013900 {
13901 // report middle speed
13902 rssidx = 1;
13903 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013904 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
13905 {
13906 // report middle speed
13907 rssidx = 2;
13908 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013909 else
13910 {
13911 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013912 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070013913 }
13914 }
13915 else
13916 {
13917 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
13918 hddLog(VOS_TRACE_LEVEL_ERROR,
13919 "%s: Invalid value for reportMaxLinkSpeed: %u",
13920 __func__, pCfg->reportMaxLinkSpeed);
13921 rssidx = 0;
13922 }
13923
13924 maxRate = 0;
13925
13926 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013927 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
13928 OperationalRates, &ORLeng))
13929 {
13930 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13931 /*To keep GUI happy*/
13932 return 0;
13933 }
13934
Jeff Johnson295189b2012-06-20 16:38:30 -070013935 for (i = 0; i < ORLeng; i++)
13936 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013937 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013938 {
13939 /* Validate Rate Set */
13940 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
13941 {
13942 currentRate = supported_data_rate[j].supported_rate[rssidx];
13943 break;
13944 }
13945 }
13946 /* Update MAX rate */
13947 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13948 }
13949
13950 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013951 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
13952 ExtendedRates, &ERLeng))
13953 {
13954 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13955 /*To keep GUI happy*/
13956 return 0;
13957 }
13958
Jeff Johnson295189b2012-06-20 16:38:30 -070013959 for (i = 0; i < ERLeng; i++)
13960 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013961 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013962 {
13963 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
13964 {
13965 currentRate = supported_data_rate[j].supported_rate[rssidx];
13966 break;
13967 }
13968 }
13969 /* Update MAX rate */
13970 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13971 }
c_hpothu79aab322014-07-14 21:11:01 +053013972
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013973 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053013974 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013975 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053013976 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070013977 {
c_hpothu79aab322014-07-14 21:11:01 +053013978 if (rate_flags & eHAL_TX_RATE_VHT80)
13979 mode = 2;
13980 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
13981 mode = 1;
13982 else
13983 mode = 0;
13984
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013985 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
13986 MCSRates, &MCSLeng))
13987 {
13988 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13989 /*To keep GUI happy*/
13990 return 0;
13991 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013992 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070013993#ifdef WLAN_FEATURE_11AC
13994 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013995 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070013996 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013997 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013998 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070013999 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070014000 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014001 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070014002 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014003 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070014004 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014005 maxMCSIdx = 7;
14006 }
14007 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
14008 {
14009 maxMCSIdx = 8;
14010 }
14011 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
14012 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014013 //VHT20 is supporting 0~8
14014 if (rate_flags & eHAL_TX_RATE_VHT20)
14015 maxMCSIdx = 8;
14016 else
14017 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070014018 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014019
c_hpothu79aab322014-07-14 21:11:01 +053014020 if (0 != rssidx)/*check for scaled */
14021 {
14022 //get middle rate MCS index if rssi=1/2
14023 for (i=0; i <= maxMCSIdx; i++)
14024 {
14025 if (sinfo->signal <= rssiMcsTbl[mode][i])
14026 {
14027 maxMCSIdx = i;
14028 break;
14029 }
14030 }
14031 }
14032
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014033 if (rate_flags & eHAL_TX_RATE_VHT80)
14034 {
14035 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
14036 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
14037 }
14038 else if (rate_flags & eHAL_TX_RATE_VHT40)
14039 {
14040 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
14041 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
14042 }
14043 else if (rate_flags & eHAL_TX_RATE_VHT20)
14044 {
14045 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
14046 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
14047 }
14048
Leo Chang6f8870f2013-03-26 18:11:36 -070014049 maxSpeedMCS = 1;
14050 if (currentRate > maxRate)
14051 {
14052 maxRate = currentRate;
14053 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014054
Leo Chang6f8870f2013-03-26 18:11:36 -070014055 }
14056 else
14057#endif /* WLAN_FEATURE_11AC */
14058 {
14059 if (rate_flags & eHAL_TX_RATE_HT40)
14060 {
14061 rateFlag |= 1;
14062 }
14063 if (rate_flags & eHAL_TX_RATE_SGI)
14064 {
14065 rateFlag |= 2;
14066 }
14067
Girish Gowli01abcee2014-07-31 20:18:55 +053014068 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053014069 if (rssidx == 1 || rssidx == 2)
14070 {
14071 //get middle rate MCS index if rssi=1/2
14072 for (i=0; i <= 7; i++)
14073 {
14074 if (sinfo->signal <= rssiMcsTbl[mode][i])
14075 {
14076 temp = i+1;
14077 break;
14078 }
14079 }
14080 }
c_hpothu79aab322014-07-14 21:11:01 +053014081
14082 for (i = 0; i < MCSLeng; i++)
14083 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014084 for (j = 0; j < temp; j++)
14085 {
14086 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
14087 {
14088 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053014089 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070014090 break;
14091 }
14092 }
14093 if ((j < temp) && (currentRate > maxRate))
14094 {
14095 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070014096 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014097 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053014098 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070014099 }
14100 }
14101
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014102 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
14103 {
14104 maxRate = myRate;
14105 maxSpeedMCS = 1;
14106 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
14107 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014108 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053014109 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070014110 {
14111 maxRate = myRate;
14112 if (rate_flags & eHAL_TX_RATE_LEGACY)
14113 {
14114 maxSpeedMCS = 0;
14115 }
14116 else
14117 {
14118 maxSpeedMCS = 1;
14119 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
14120 }
14121 }
14122
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014123 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070014124 {
14125 sinfo->txrate.legacy = maxRate;
14126#ifdef LINKSPEED_DEBUG_ENABLED
14127 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
14128#endif //LINKSPEED_DEBUG_ENABLED
14129 }
14130 else
14131 {
14132 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070014133#ifdef WLAN_FEATURE_11AC
14134 sinfo->txrate.nss = 1;
14135 if (rate_flags & eHAL_TX_RATE_VHT80)
14136 {
14137 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014138 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070014139 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014140 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070014141 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014142 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14143 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14144 }
14145 else if (rate_flags & eHAL_TX_RATE_VHT20)
14146 {
14147 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14148 }
14149#endif /* WLAN_FEATURE_11AC */
14150 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
14151 {
14152 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14153 if (rate_flags & eHAL_TX_RATE_HT40)
14154 {
14155 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14156 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014157 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014158 if (rate_flags & eHAL_TX_RATE_SGI)
14159 {
14160 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14161 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014162
Jeff Johnson295189b2012-06-20 16:38:30 -070014163#ifdef LINKSPEED_DEBUG_ENABLED
14164 pr_info("Reporting MCS rate %d flags %x\n",
14165 sinfo->txrate.mcs,
14166 sinfo->txrate.flags );
14167#endif //LINKSPEED_DEBUG_ENABLED
14168 }
14169 }
14170 else
14171 {
14172 // report current rate instead of max rate
14173
14174 if (rate_flags & eHAL_TX_RATE_LEGACY)
14175 {
14176 //provide to the UI in units of 100kbps
14177 sinfo->txrate.legacy = myRate;
14178#ifdef LINKSPEED_DEBUG_ENABLED
14179 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
14180#endif //LINKSPEED_DEBUG_ENABLED
14181 }
14182 else
14183 {
14184 //must be MCS
14185 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070014186#ifdef WLAN_FEATURE_11AC
14187 sinfo->txrate.nss = 1;
14188 if (rate_flags & eHAL_TX_RATE_VHT80)
14189 {
14190 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14191 }
14192 else
14193#endif /* WLAN_FEATURE_11AC */
14194 {
14195 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14196 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014197 if (rate_flags & eHAL_TX_RATE_SGI)
14198 {
14199 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14200 }
14201 if (rate_flags & eHAL_TX_RATE_HT40)
14202 {
14203 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14204 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014205#ifdef WLAN_FEATURE_11AC
14206 else if (rate_flags & eHAL_TX_RATE_VHT80)
14207 {
14208 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
14209 }
14210#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070014211#ifdef LINKSPEED_DEBUG_ENABLED
14212 pr_info("Reporting actual MCS rate %d flags %x\n",
14213 sinfo->txrate.mcs,
14214 sinfo->txrate.flags );
14215#endif //LINKSPEED_DEBUG_ENABLED
14216 }
14217 }
14218 sinfo->filled |= STATION_INFO_TX_BITRATE;
14219
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014220 sinfo->tx_packets =
14221 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
14222 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
14223 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
14224 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
14225
14226 sinfo->tx_retries =
14227 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
14228 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
14229 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
14230 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
14231
14232 sinfo->tx_failed =
14233 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
14234 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
14235 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
14236 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
14237
14238 sinfo->filled |=
14239 STATION_INFO_TX_PACKETS |
14240 STATION_INFO_TX_RETRIES |
14241 STATION_INFO_TX_FAILED;
14242
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014243 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14244 TRACE_CODE_HDD_CFG80211_GET_STA,
14245 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014246 EXIT();
14247 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014248}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014249#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14250static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14251 const u8* mac, struct station_info *sinfo)
14252#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014253static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14254 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014255#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014256{
14257 int ret;
14258
14259 vos_ssr_protect(__func__);
14260 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
14261 vos_ssr_unprotect(__func__);
14262
14263 return ret;
14264}
14265
14266static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070014267 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070014268{
14269 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014270 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014271 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014272 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014273
Jeff Johnsone7245742012-09-05 17:12:55 -070014274 ENTER();
14275
Jeff Johnson295189b2012-06-20 16:38:30 -070014276 if (NULL == pAdapter)
14277 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014278 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014279 return -ENODEV;
14280 }
14281
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014282 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14283 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
14284 pAdapter->sessionId, timeout));
14285
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014286 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014287 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014288 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014289 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014290 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014291 }
14292
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014293 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
14294 (TRUE == pHddCtx->hdd_wlan_suspended) &&
14295 (pHddCtx->cfg_ini->fhostArpOffload) &&
14296 (eConnectionState_Associated ==
14297 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14298 {
Amar Singhald53568e2013-09-26 11:03:45 -070014299
14300 hddLog(VOS_TRACE_LEVEL_INFO,
14301 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053014302 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014303 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14304 {
14305 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014306 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014307 __func__, vos_status);
14308 }
14309 }
14310
Jeff Johnson295189b2012-06-20 16:38:30 -070014311 /**The get power cmd from the supplicant gets updated by the nl only
14312 *on successful execution of the function call
14313 *we are oppositely mapped w.r.t mode in the driver
14314 **/
14315 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
14316
14317 if (VOS_STATUS_E_FAILURE == vos_status)
14318 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14320 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014321 return -EINVAL;
14322 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014323 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014324 return 0;
14325}
14326
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014327static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
14328 struct net_device *dev, bool mode, int timeout)
14329{
14330 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014331
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014332 vos_ssr_protect(__func__);
14333 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
14334 vos_ssr_unprotect(__func__);
14335
14336 return ret;
14337}
Sushant Kaushik084f6592015-09-10 13:11:56 +053014338static const struct
14339nla_policy
14340qca_wlan_vendor_get_wifi_info_policy[
14341 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
14342 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
14343 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
14344};
14345
14346/**
14347 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
14348 * @wiphy: pointer to wireless wiphy structure.
14349 * @wdev: pointer to wireless_dev structure.
14350 * @data: Pointer to the data to be passed via vendor interface
14351 * @data_len:Length of the data to be passed
14352 *
14353 * This is called when wlan driver needs to send wifi driver related info
14354 * (driver/fw version) to the user space application upon request.
14355 *
14356 * Return: Return the Success or Failure code.
14357 */
14358static int
14359wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
14360 struct wireless_dev *wdev,
14361 const void *data, int data_len)
14362{
14363 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
14364 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
14365 tSirVersionString version;
14366 uint32 version_len;
14367 uint8 attr;
14368 int status;
14369 struct sk_buff *reply_skb = NULL;
14370
14371 if (VOS_FTM_MODE == hdd_get_conparam()) {
14372 hddLog(LOGE, FL("Command not allowed in FTM mode"));
14373 return -EINVAL;
14374 }
14375
14376 status = wlan_hdd_validate_context(hdd_ctx);
14377 if (0 != status) {
14378 hddLog(LOGE, FL("HDD context is not valid"));
14379 return -EINVAL;
14380 }
14381
14382 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
14383 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
14384 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
14385 return -EINVAL;
14386 }
14387
14388 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
14389 hddLog(LOG1, FL("Rcvd req for Driver version "
14390 "Driver version is %s"),QWLAN_VERSIONSTR);
14391 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
14392 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
14393 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
14394 hddLog(LOG1, FL("Rcvd req for FW version "
14395 "FW version is %s"), hdd_ctx->fw_Version);
14396 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
14397 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
14398 } else {
14399 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
14400 return -EINVAL;
14401 }
14402
14403 version_len = strlen(version);
14404 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
14405 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
14406 if (!reply_skb) {
14407 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
14408 return -ENOMEM;
14409 }
14410
14411 if (nla_put(reply_skb, attr, version_len, version)) {
14412 hddLog(LOGE, FL("nla put fail"));
14413 kfree_skb(reply_skb);
14414 return -EINVAL;
14415 }
14416
14417 return cfg80211_vendor_cmd_reply(reply_skb);
14418}
14419
Jeff Johnson295189b2012-06-20 16:38:30 -070014420#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014421static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
14422 struct net_device *netdev,
14423 u8 key_index)
14424{
14425 ENTER();
14426 return 0;
14427}
14428
Jeff Johnson295189b2012-06-20 16:38:30 -070014429static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014430 struct net_device *netdev,
14431 u8 key_index)
14432{
14433 int ret;
14434 vos_ssr_protect(__func__);
14435 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
14436 vos_ssr_unprotect(__func__);
14437 return ret;
14438}
14439#endif //LINUX_VERSION_CODE
14440
14441#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14442static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14443 struct net_device *dev,
14444 struct ieee80211_txq_params *params)
14445{
14446 ENTER();
14447 return 0;
14448}
14449#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14450static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14451 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014452{
Jeff Johnsone7245742012-09-05 17:12:55 -070014453 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070014454 return 0;
14455}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014456#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070014457
14458#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14459static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014460 struct net_device *dev,
14461 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014462{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014463 int ret;
14464
14465 vos_ssr_protect(__func__);
14466 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
14467 vos_ssr_unprotect(__func__);
14468 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014469}
14470#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14471static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
14472 struct ieee80211_txq_params *params)
14473{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014474 int ret;
14475
14476 vos_ssr_protect(__func__);
14477 ret = __wlan_hdd_set_txq_params(wiphy, params);
14478 vos_ssr_unprotect(__func__);
14479 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014480}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014481#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014482
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014483static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014484 struct net_device *dev,
14485 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070014486{
14487 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014488 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014489 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014490 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014491 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014492 v_CONTEXT_t pVosContext = NULL;
14493 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014494
Jeff Johnsone7245742012-09-05 17:12:55 -070014495 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014496
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014497 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070014498 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014499 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014500 return -EINVAL;
14501 }
14502
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014503 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14504 TRACE_CODE_HDD_CFG80211_DEL_STA,
14505 pAdapter->sessionId, pAdapter->device_mode));
14506
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014507 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14508 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014509 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014510 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014511 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014512 }
14513
Jeff Johnson295189b2012-06-20 16:38:30 -070014514 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014515 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014516 )
14517 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014518 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14519 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14520 if(pSapCtx == NULL){
14521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14522 FL("psapCtx is NULL"));
14523 return -ENOENT;
14524 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014525 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070014526 {
14527 v_U16_t i;
14528 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
14529 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014530 if ((pSapCtx->aStaInfo[i].isUsed) &&
14531 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070014532 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014533 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014534 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014535 ETHER_ADDR_LEN);
14536
Jeff Johnson295189b2012-06-20 16:38:30 -070014537 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014538 "%s: Delete STA with MAC::"
14539 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014540 __func__,
14541 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
14542 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070014543 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014544 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014545 }
14546 }
14547 }
14548 else
14549 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014550
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014551 vos_status = hdd_softap_GetStaId(pAdapter,
14552 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014553 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14554 {
14555 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014556 "%s: Skip this DEL STA as this is not used::"
14557 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014558 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014559 return -ENOENT;
14560 }
14561
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014562 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014563 {
14564 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014565 "%s: Skip this DEL STA as deauth is in progress::"
14566 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014567 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014568 return -ENOENT;
14569 }
14570
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014571 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014572
Jeff Johnson295189b2012-06-20 16:38:30 -070014573 hddLog(VOS_TRACE_LEVEL_INFO,
14574 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014575 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014576 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014577 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014578
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014579 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014580 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14581 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014582 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014583 hddLog(VOS_TRACE_LEVEL_INFO,
14584 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014585 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014586 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014587 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014588 return -ENOENT;
14589 }
14590
Jeff Johnson295189b2012-06-20 16:38:30 -070014591 }
14592 }
14593
14594 EXIT();
14595
14596 return 0;
14597}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014598
14599#ifdef CFG80211_DEL_STA_V2
14600static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14601 struct net_device *dev,
14602 struct station_del_parameters *param)
14603#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014604#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14605static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14606 struct net_device *dev, const u8 *mac)
14607#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014608static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14609 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014610#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014611#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014612{
14613 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014614 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070014615
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014616 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014617
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014618#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014619 if (NULL == param) {
14620 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014621 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014622 return -EINVAL;
14623 }
14624
14625 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
14626 param->subtype, &delStaParams);
14627
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014628#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014629 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014630 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014631#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014632 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
14633
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014634 vos_ssr_unprotect(__func__);
14635
14636 return ret;
14637}
14638
14639static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014640 struct net_device *dev,
14641#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14642 const u8 *mac,
14643#else
14644 u8 *mac,
14645#endif
14646 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014647{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014648 hdd_adapter_t *pAdapter;
14649 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014650 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014651#ifdef FEATURE_WLAN_TDLS
14652 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014653
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014654 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014655
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014656 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14657 if (NULL == pAdapter)
14658 {
14659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14660 "%s: Adapter is NULL",__func__);
14661 return -EINVAL;
14662 }
14663 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14664 status = wlan_hdd_validate_context(pHddCtx);
14665 if (0 != status)
14666 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014667 return status;
14668 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014669
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014670 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14671 TRACE_CODE_HDD_CFG80211_ADD_STA,
14672 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014673 mask = params->sta_flags_mask;
14674
14675 set = params->sta_flags_set;
14676
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014677 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014678 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
14679 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014680
14681 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
14682 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014683 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014684 }
14685 }
14686#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014687 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014688 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014689}
14690
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014691#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14692static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14693 struct net_device *dev, const u8 *mac,
14694 struct station_parameters *params)
14695#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014696static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14697 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014698#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014699{
14700 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014701
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014702 vos_ssr_protect(__func__);
14703 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
14704 vos_ssr_unprotect(__func__);
14705
14706 return ret;
14707}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014708#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070014709
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014710static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070014711 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014712{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014713 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14714 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014715 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014716 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014717 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014718 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070014719
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014720 ENTER();
14721
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014722 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014723 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014724 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014725 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014726 return -EINVAL;
14727 }
14728
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014729 if (!pmksa) {
14730 hddLog(LOGE, FL("pmksa is NULL"));
14731 return -EINVAL;
14732 }
14733
14734 if (!pmksa->bssid || !pmksa->pmkid) {
14735 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
14736 pmksa->bssid, pmksa->pmkid);
14737 return -EINVAL;
14738 }
14739
14740 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
14741 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14742
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014743 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14744 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014745 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014746 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014747 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014748 }
14749
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014750 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014751 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14752
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014753 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
14754 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014755
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014756 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014757 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014758 &pmk_id, 1, FALSE);
14759
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014760 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14761 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
14762 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014763
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014764 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014765 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014766}
14767
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014768static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
14769 struct cfg80211_pmksa *pmksa)
14770{
14771 int ret;
14772
14773 vos_ssr_protect(__func__);
14774 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
14775 vos_ssr_unprotect(__func__);
14776
14777 return ret;
14778}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014779
Wilson Yang6507c4e2013-10-01 20:11:19 -070014780
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014781static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070014782 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014783{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014784 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14785 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014786 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014787 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014788
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014789 ENTER();
14790
Wilson Yang6507c4e2013-10-01 20:11:19 -070014791 /* Validate pAdapter */
14792 if (NULL == pAdapter)
14793 {
14794 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
14795 return -EINVAL;
14796 }
14797
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014798 if (!pmksa) {
14799 hddLog(LOGE, FL("pmksa is NULL"));
14800 return -EINVAL;
14801 }
14802
14803 if (!pmksa->bssid) {
14804 hddLog(LOGE, FL("pmksa->bssid is NULL"));
14805 return -EINVAL;
14806 }
14807
Kiet Lam98c46a12014-10-31 15:34:57 -070014808 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
14809 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14810
Wilson Yang6507c4e2013-10-01 20:11:19 -070014811 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14812 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014813 if (0 != status)
14814 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014815 return status;
14816 }
14817
14818 /*Retrieve halHandle*/
14819 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14820
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014821 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14822 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
14823 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014824 /* Delete the PMKID CSR cache */
14825 if (eHAL_STATUS_SUCCESS !=
14826 sme_RoamDelPMKIDfromCache(halHandle,
14827 pAdapter->sessionId, pmksa->bssid, FALSE)) {
14828 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
14829 MAC_ADDR_ARRAY(pmksa->bssid));
14830 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014831 }
14832
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014833 EXIT();
14834 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014835}
14836
Wilson Yang6507c4e2013-10-01 20:11:19 -070014837
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014838static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
14839 struct cfg80211_pmksa *pmksa)
14840{
14841 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014842
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014843 vos_ssr_protect(__func__);
14844 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
14845 vos_ssr_unprotect(__func__);
14846
14847 return ret;
14848
14849}
14850
14851static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014852{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014853 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14854 tHalHandle halHandle;
14855 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014856 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014857
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014858 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070014859
14860 /* Validate pAdapter */
14861 if (NULL == pAdapter)
14862 {
14863 hddLog(VOS_TRACE_LEVEL_ERROR,
14864 "%s: Invalid Adapter" ,__func__);
14865 return -EINVAL;
14866 }
14867
14868 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14869 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014870 if (0 != status)
14871 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014872 return status;
14873 }
14874
14875 /*Retrieve halHandle*/
14876 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14877
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014878 /* Flush the PMKID cache in CSR */
14879 if (eHAL_STATUS_SUCCESS !=
14880 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
14881 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
14882 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014883 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014884 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080014885 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014886}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014887
14888static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
14889{
14890 int ret;
14891
14892 vos_ssr_protect(__func__);
14893 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
14894 vos_ssr_unprotect(__func__);
14895
14896 return ret;
14897}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014898#endif
14899
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014900#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014901static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14902 struct net_device *dev,
14903 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014904{
14905 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14906 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014907 hdd_context_t *pHddCtx;
14908 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014909
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014910 ENTER();
14911
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014912 if (NULL == pAdapter)
14913 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014914 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014915 return -ENODEV;
14916 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014917 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14918 ret = wlan_hdd_validate_context(pHddCtx);
14919 if (0 != ret)
14920 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014921 return ret;
14922 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014923 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014924 if (NULL == pHddStaCtx)
14925 {
14926 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
14927 return -EINVAL;
14928 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014929
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014930 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14931 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
14932 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014933 // Added for debug on reception of Re-assoc Req.
14934 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
14935 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014936 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014937 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080014938 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014939 }
14940
14941#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080014942 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014943 ftie->ie_len);
14944#endif
14945
14946 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014947 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
14948 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014949 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014950
14951 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014952 return 0;
14953}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014954
14955static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14956 struct net_device *dev,
14957 struct cfg80211_update_ft_ies_params *ftie)
14958{
14959 int ret;
14960
14961 vos_ssr_protect(__func__);
14962 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
14963 vos_ssr_unprotect(__func__);
14964
14965 return ret;
14966}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014967#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014968
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014969#ifdef FEATURE_WLAN_SCAN_PNO
14970
14971void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
14972 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
14973{
14974 int ret;
14975 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
14976 hdd_context_t *pHddCtx;
14977
Nirav Shah80830bf2013-12-31 16:35:12 +053014978 ENTER();
14979
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014980 if (NULL == pAdapter)
14981 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014982 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014983 "%s: HDD adapter is Null", __func__);
14984 return ;
14985 }
14986
14987 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14988 if (NULL == pHddCtx)
14989 {
14990 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14991 "%s: HDD context is Null!!!", __func__);
14992 return ;
14993 }
14994
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014995 spin_lock(&pHddCtx->schedScan_lock);
14996 if (TRUE == pHddCtx->isWiphySuspended)
14997 {
14998 pHddCtx->isSchedScanUpdatePending = TRUE;
14999 spin_unlock(&pHddCtx->schedScan_lock);
15000 hddLog(VOS_TRACE_LEVEL_INFO,
15001 "%s: Update cfg80211 scan database after it resume", __func__);
15002 return ;
15003 }
15004 spin_unlock(&pHddCtx->schedScan_lock);
15005
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015006 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
15007
15008 if (0 > ret)
15009 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
15010
15011 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015012 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15013 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015014}
15015
15016/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015017 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015018 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015019 */
15020static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
15021{
15022 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15023 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015024 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015025 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15026 int status = 0;
15027 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
15028
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015029 /* The current firmware design does not allow PNO during any
15030 * active sessions. Hence, determine the active sessions
15031 * and return a failure.
15032 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015033 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
15034 {
15035 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015036 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015037
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015038 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
15039 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
15040 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
15041 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
15042 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053015043 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015044 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015045 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015046 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015047 }
15048 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15049 pAdapterNode = pNext;
15050 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015051 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015052}
15053
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015054void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
15055{
15056 hdd_adapter_t *pAdapter = callbackContext;
15057 hdd_context_t *pHddCtx;
15058
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015059 ENTER();
15060
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015061 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
15062 {
15063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15064 FL("Invalid adapter or adapter has invalid magic"));
15065 return;
15066 }
15067
15068 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15069 if (0 != wlan_hdd_validate_context(pHddCtx))
15070 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015071 return;
15072 }
15073
c_hpothub53c45d2014-08-18 16:53:14 +053015074 if (VOS_STATUS_SUCCESS != status)
15075 {
15076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015077 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053015078 pHddCtx->isPnoEnable = FALSE;
15079 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015080
15081 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
15082 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015083 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015084}
15085
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015086/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015087 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
15088 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015089 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015090static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015091 struct net_device *dev, struct cfg80211_sched_scan_request *request)
15092{
15093 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015094 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015095 hdd_context_t *pHddCtx;
15096 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015097 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053015098 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
15099 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015100 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15101 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015102 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015103 hdd_config_t *pConfig = NULL;
15104 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015105
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015106 ENTER();
15107
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015108 if (NULL == pAdapter)
15109 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015111 "%s: HDD adapter is Null", __func__);
15112 return -ENODEV;
15113 }
15114
15115 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015116 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015117
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015118 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015119 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015120 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015121 }
15122
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015123 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015124 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15125 if (NULL == hHal)
15126 {
15127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15128 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015129 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015130 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015131 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15132 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
15133 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053015134 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015135 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053015136 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015137 {
15138 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15139 "%s: aborting the existing scan is unsuccessfull", __func__);
15140 return -EBUSY;
15141 }
15142
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015143 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015144 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015146 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015147 return -EBUSY;
15148 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015149
c_hpothu37f21312014-04-09 21:49:54 +053015150 if (TRUE == pHddCtx->isPnoEnable)
15151 {
15152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15153 FL("already PNO is enabled"));
15154 return -EBUSY;
15155 }
c_hpothu225aa7c2014-10-22 17:45:13 +053015156
15157 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
15158 {
15159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15160 "%s: abort ROC failed ", __func__);
15161 return -EBUSY;
15162 }
15163
c_hpothu37f21312014-04-09 21:49:54 +053015164 pHddCtx->isPnoEnable = TRUE;
15165
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015166 pnoRequest.enable = 1; /*Enable PNO */
15167 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015168
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015169 if (( !pnoRequest.ucNetworksCount ) ||
15170 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015171 {
15172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015173 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015174 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015175 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015176 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015177 goto error;
15178 }
15179
15180 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
15181 {
15182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015183 "%s: Incorrect number of channels %d",
15184 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015185 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015186 goto error;
15187 }
15188
15189 /* Framework provides one set of channels(all)
15190 * common for all saved profile */
15191 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15192 channels_allowed, &num_channels_allowed))
15193 {
15194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15195 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015196 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015197 goto error;
15198 }
15199 /* Checking each channel against allowed channel list */
15200 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053015201 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015202 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015203 char chList [(request->n_channels*5)+1];
15204 int len;
15205 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015206 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015207 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015208 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015209 if (request->channels[i]->hw_value == channels_allowed[indx])
15210 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015211 if ((!pConfig->enableDFSPnoChnlScan) &&
15212 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
15213 {
15214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15215 "%s : Dropping DFS channel : %d",
15216 __func__,channels_allowed[indx]);
15217 num_ignore_dfs_ch++;
15218 break;
15219 }
15220
Nirav Shah80830bf2013-12-31 16:35:12 +053015221 valid_ch[num_ch++] = request->channels[i]->hw_value;
15222 len += snprintf(chList+len, 5, "%d ",
15223 request->channels[i]->hw_value);
15224 break ;
15225 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015226 }
15227 }
Nirav Shah80830bf2013-12-31 16:35:12 +053015228 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015229
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015230 /*If all channels are DFS and dropped, then ignore the PNO request*/
15231 if (num_ignore_dfs_ch == request->n_channels)
15232 {
15233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15234 "%s : All requested channels are DFS channels", __func__);
15235 ret = -EINVAL;
15236 goto error;
15237 }
15238 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015239
15240 pnoRequest.aNetworks =
15241 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15242 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015243 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015244 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15245 FL("failed to allocate memory aNetworks %u"),
15246 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15247 goto error;
15248 }
15249 vos_mem_zero(pnoRequest.aNetworks,
15250 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15251
15252 /* Filling per profile params */
15253 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
15254 {
15255 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015256 request->match_sets[i].ssid.ssid_len;
15257
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015258 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
15259 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015260 {
15261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015262 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015263 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015264 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015265 goto error;
15266 }
15267
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015268 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015269 request->match_sets[i].ssid.ssid,
15270 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15272 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015273 i, pnoRequest.aNetworks[i].ssId.ssId);
15274 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
15275 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
15276 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015277
15278 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015279 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
15280 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015281
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015282 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015283 }
15284
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015285 for (i = 0; i < request->n_ssids; i++)
15286 {
15287 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015288 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015289 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015290 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015291 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015292 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015293 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015294 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015295 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015296 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015297 break;
15298 }
15299 j++;
15300 }
15301 }
15302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15303 "Number of hidden networks being Configured = %d",
15304 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080015306 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015307
15308 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15309 if (pnoRequest.p24GProbeTemplate == NULL)
15310 {
15311 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15312 FL("failed to allocate memory p24GProbeTemplate %u"),
15313 SIR_PNO_MAX_PB_REQ_SIZE);
15314 goto error;
15315 }
15316
15317 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15318 if (pnoRequest.p5GProbeTemplate == NULL)
15319 {
15320 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15321 FL("failed to allocate memory p5GProbeTemplate %u"),
15322 SIR_PNO_MAX_PB_REQ_SIZE);
15323 goto error;
15324 }
15325
15326 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15327 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15328
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053015329 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
15330 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015331 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015332 pnoRequest.us24GProbeTemplateLen = request->ie_len;
15333 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
15334 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015335
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015336 pnoRequest.us5GProbeTemplateLen = request->ie_len;
15337 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
15338 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015339 }
15340
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015341 /* Driver gets only one time interval which is hardcoded in
15342 * supplicant for 10000ms. Taking power consumption into account 6 timers
15343 * will be used, Timervalue is increased exponentially i.e 10,20,40,
15344 * 80,160,320 secs. And number of scan cycle for each timer
15345 * is configurable through INI param gPNOScanTimerRepeatValue.
15346 * If it is set to 0 only one timer will be used and PNO scan cycle
15347 * will be repeated after each interval specified by supplicant
15348 * till PNO is disabled.
15349 */
15350 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015351 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015352 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015353 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015354 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
15355
15356 tempInterval = (request->interval)/1000;
15357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15358 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
15359 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015360 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015361 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015362 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015363 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015364 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015365 tempInterval *= 2;
15366 }
15367 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015368 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015369
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015370 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015371
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015372 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015373 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
15374 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015375 pAdapter->pno_req_status = 0;
15376
Nirav Shah80830bf2013-12-31 16:35:12 +053015377 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15378 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015379 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
15380 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053015381
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015382 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015383 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015384 hdd_cfg80211_sched_scan_done_callback, pAdapter);
15385 if (eHAL_STATUS_SUCCESS != status)
15386 {
15387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015388 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015389 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015390 goto error;
15391 }
15392
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015393 ret = wait_for_completion_timeout(
15394 &pAdapter->pno_comp_var,
15395 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
15396 if (0 >= ret)
15397 {
15398 // Did not receive the response for PNO enable in time.
15399 // Assuming the PNO enable was success.
15400 // Returning error from here, because we timeout, results
15401 // in side effect of Wifi (Wifi Setting) not to work.
15402 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15403 FL("Timed out waiting for PNO to be Enabled"));
15404 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015405 }
15406
15407 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053015408 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015409
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015410error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15412 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053015413 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015414 if (pnoRequest.aNetworks)
15415 vos_mem_free(pnoRequest.aNetworks);
15416 if (pnoRequest.p24GProbeTemplate)
15417 vos_mem_free(pnoRequest.p24GProbeTemplate);
15418 if (pnoRequest.p5GProbeTemplate)
15419 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015420
15421 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015422 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015423}
15424
15425/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015426 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
15427 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015428 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015429static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
15430 struct net_device *dev, struct cfg80211_sched_scan_request *request)
15431{
15432 int ret;
15433
15434 vos_ssr_protect(__func__);
15435 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
15436 vos_ssr_unprotect(__func__);
15437
15438 return ret;
15439}
15440
15441/*
15442 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
15443 * Function to disable PNO
15444 */
15445static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015446 struct net_device *dev)
15447{
15448 eHalStatus status = eHAL_STATUS_FAILURE;
15449 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15450 hdd_context_t *pHddCtx;
15451 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015452 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015453 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015454
15455 ENTER();
15456
15457 if (NULL == pAdapter)
15458 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015459 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015460 "%s: HDD adapter is Null", __func__);
15461 return -ENODEV;
15462 }
15463
15464 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015465
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015466 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015467 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015469 "%s: HDD context is Null", __func__);
15470 return -ENODEV;
15471 }
15472
15473 /* The return 0 is intentional when isLogpInProgress and
15474 * isLoadUnloadInProgress. We did observe a crash due to a return of
15475 * failure in sched_scan_stop , especially for a case where the unload
15476 * of the happens at the same time. The function __cfg80211_stop_sched_scan
15477 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
15478 * success. If it returns a failure , then its next invocation due to the
15479 * clean up of the second interface will have the dev pointer corresponding
15480 * to the first one leading to a crash.
15481 */
15482 if (pHddCtx->isLogpInProgress)
15483 {
15484 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15485 "%s: LOGP in Progress. Ignore!!!", __func__);
15486 return ret;
15487 }
15488
Mihir Shete18156292014-03-11 15:38:30 +053015489 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015490 {
15491 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15492 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15493 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015494 }
15495
15496 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15497 if (NULL == hHal)
15498 {
15499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15500 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015501 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015502 }
15503
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015504 pnoRequest.enable = 0; /* Disable PNO */
15505 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015506
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015507 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15508 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
15509 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015510 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015511 pAdapter->sessionId,
15512 NULL, pAdapter);
15513 if (eHAL_STATUS_SUCCESS != status)
15514 {
15515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15516 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015517 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015518 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015519 }
c_hpothu37f21312014-04-09 21:49:54 +053015520 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015521
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015522error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015523 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015524 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015525
15526 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015527 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015528}
15529
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015530/*
15531 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
15532 * NL interface to disable PNO
15533 */
15534static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
15535 struct net_device *dev)
15536{
15537 int ret;
15538
15539 vos_ssr_protect(__func__);
15540 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
15541 vos_ssr_unprotect(__func__);
15542
15543 return ret;
15544}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015545#endif /*FEATURE_WLAN_SCAN_PNO*/
15546
15547
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015548#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015549#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015550static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15551 struct net_device *dev,
15552 u8 *peer, u8 action_code,
15553 u8 dialog_token,
15554 u16 status_code, u32 peer_capability,
15555 const u8 *buf, size_t len)
15556#else /* TDLS_MGMT_VERSION2 */
15557#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
15558static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15559 struct net_device *dev,
15560 const u8 *peer, u8 action_code,
15561 u8 dialog_token, u16 status_code,
15562 u32 peer_capability, bool initiator,
15563 const u8 *buf, size_t len)
15564#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
15565static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15566 struct net_device *dev,
15567 const u8 *peer, u8 action_code,
15568 u8 dialog_token, u16 status_code,
15569 u32 peer_capability, const u8 *buf,
15570 size_t len)
15571#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
15572static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15573 struct net_device *dev,
15574 u8 *peer, u8 action_code,
15575 u8 dialog_token,
15576 u16 status_code, u32 peer_capability,
15577 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015578#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015579static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15580 struct net_device *dev,
15581 u8 *peer, u8 action_code,
15582 u8 dialog_token,
15583 u16 status_code, const u8 *buf,
15584 size_t len)
15585#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015586#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015587{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015588 hdd_adapter_t *pAdapter;
15589 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015590 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070015591 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080015592 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070015593 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015594 int ret;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015595#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015596 u32 peer_capability = 0;
15597#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015598 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015599 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015600
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015601 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15602 if (NULL == pAdapter)
15603 {
15604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15605 "%s: Adapter is NULL",__func__);
15606 return -EINVAL;
15607 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015608 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15609 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
15610 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015611
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015612 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015613 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015614 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015615 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015616 "Invalid arguments");
15617 return -EINVAL;
15618 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015619
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015620 if (pHddCtx->isLogpInProgress)
15621 {
15622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15623 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053015624 wlan_hdd_tdls_set_link_status(pAdapter,
15625 peer,
15626 eTDLS_LINK_IDLE,
15627 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015628 return -EBUSY;
15629 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015630
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015631 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
15632 {
15633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15634 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15635 return -EAGAIN;
15636 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015637
Hoonki Lee27511902013-03-14 18:19:06 -070015638 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015639 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015641 "%s: TDLS mode is disabled OR not enabled in FW."
15642 MAC_ADDRESS_STR " action %d declined.",
15643 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015644 return -ENOTSUPP;
15645 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015646
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015647 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15648
15649 if( NULL == pHddStaCtx )
15650 {
15651 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15652 "%s: HDD station context NULL ",__func__);
15653 return -EINVAL;
15654 }
15655
15656 /* STA should be connected and authenticated
15657 * before sending any TDLS frames
15658 */
15659 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15660 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
15661 {
15662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15663 "STA is not connected or unauthenticated. "
15664 "connState %u, uIsAuthenticated %u",
15665 pHddStaCtx->conn_info.connState,
15666 pHddStaCtx->conn_info.uIsAuthenticated);
15667 return -EAGAIN;
15668 }
15669
Hoonki Lee27511902013-03-14 18:19:06 -070015670 /* other than teardown frame, other mgmt frames are not sent if disabled */
15671 if (SIR_MAC_TDLS_TEARDOWN != action_code)
15672 {
15673 /* if tdls_mode is disabled to respond to peer's request */
15674 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
15675 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015677 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015678 " TDLS mode is disabled. action %d declined.",
15679 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070015680
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015681 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070015682 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053015683
15684 if (vos_max_concurrent_connections_reached())
15685 {
15686 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15687 return -EINVAL;
15688 }
Hoonki Lee27511902013-03-14 18:19:06 -070015689 }
15690
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015691 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
15692 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053015693 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015694 {
15695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015696 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015697 " TDLS setup is ongoing. action %d declined.",
15698 __func__, MAC_ADDR_ARRAY(peer), action_code);
15699 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015700 }
15701 }
15702
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015703 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
15704 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080015705 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015706 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15707 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015708 {
15709 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
15710 we return error code at 'add_station()'. Hence we have this
15711 check again in addtion to add_station().
15712 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015713 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015714 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015715 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15716 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015717 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
15718 __func__, MAC_ADDR_ARRAY(peer), action_code,
15719 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053015720 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080015721 }
15722 else
15723 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015724 /* maximum reached. tweak to send error code to peer and return
15725 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015726 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15728 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015729 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
15730 __func__, MAC_ADDR_ARRAY(peer), status_code,
15731 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070015732 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015733 /* fall through to send setup resp with failure status
15734 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015735 }
15736 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015737 else
15738 {
15739 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053015740 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015741 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015742 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015744 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
15745 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015746 return -EPERM;
15747 }
15748 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015749 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015750
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015752 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015753 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
15754 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015755
Hoonki Leea34dd892013-02-05 22:56:02 -080015756 /*Except teardown responder will not be used so just make 0*/
15757 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015758 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080015759 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015760
15761 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015762 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015763
15764 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
15765 responder = pTdlsPeer->is_responder;
15766 else
Hoonki Leea34dd892013-02-05 22:56:02 -080015767 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015769 "%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 -070015770 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
15771 dialog_token, status_code, len);
15772 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080015773 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015774 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015775
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015776 /* For explicit trigger of DIS_REQ come out of BMPS for
15777 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070015778 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015779 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
15780 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070015781 {
15782 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
15783 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015784 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015785 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015786 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
15787 if (status != VOS_STATUS_SUCCESS) {
15788 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
15789 }
Hoonki Lee14621352013-04-16 17:51:19 -070015790 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015791 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015792 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015793 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
15794 }
15795 }
Hoonki Lee14621352013-04-16 17:51:19 -070015796 }
15797
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015798 /* make sure doesn't call send_mgmt() while it is pending */
15799 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
15800 {
15801 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015802 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015803 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015804 ret = -EBUSY;
15805 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015806 }
15807
15808 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015809 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
15810
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015811 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
15812 pAdapter->sessionId, peer, action_code, dialog_token,
15813 status_code, peer_capability, (tANI_U8 *)buf, len,
15814 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015815
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015816 if (VOS_STATUS_SUCCESS != status)
15817 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15819 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015820 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015821 ret = -EINVAL;
15822 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015823 }
15824
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015825 if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
15826 (SIR_MAC_TDLS_DIS_RSP == action_code))
15827 {
15828 /* for DIS_REQ/DIS_RSP, supplicant don't consider the return status.
15829 * So we no need to wait for tdls_mgmt_comp for sending ack status.
15830 */
15831 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15832 "%s: tx done for frm %u", __func__, action_code);
15833 return 0;
15834 }
15835
15836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15837 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
15838 WAIT_TIME_TDLS_MGMT);
15839
Hoonki Leed37cbb32013-04-20 00:31:14 -070015840 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
15841 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
15842
15843 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015844 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070015845 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015846 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070015847 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015848 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080015849
15850 if (pHddCtx->isLogpInProgress)
15851 {
15852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15853 "%s: LOGP in Progress. Ignore!!!", __func__);
15854 return -EAGAIN;
15855 }
15856
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015857 ret = -EINVAL;
15858 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015859 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015860 else
15861 {
15862 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15863 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
15864 __func__, rc, pAdapter->mgmtTxCompletionStatus);
15865 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015866
Gopichand Nakkala05922802013-03-14 12:23:19 -070015867 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070015868 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015869 ret = max_sta_failed;
15870 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070015871 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015872
Hoonki Leea34dd892013-02-05 22:56:02 -080015873 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
15874 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015875 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015876 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15877 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015878 }
15879 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
15880 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015881 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015882 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15883 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015884 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015885
15886 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015887
15888tx_failed:
15889 /* add_station will be called before sending TDLS_SETUP_REQ and
15890 * TDLS_SETUP_RSP and as part of add_station driver will enable
15891 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
15892 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
15893 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
15894 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
15895 */
15896
15897 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
15898 (SIR_MAC_TDLS_SETUP_RSP == action_code))
15899 wlan_hdd_tdls_check_bmps(pAdapter);
15900 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015901}
15902
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015903#if TDLS_MGMT_VERSION2
15904static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15905 u8 *peer, u8 action_code, u8 dialog_token,
15906 u16 status_code, u32 peer_capability,
15907 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015908#else /* TDLS_MGMT_VERSION2 */
15909#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
15910static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15911 struct net_device *dev,
15912 const u8 *peer, u8 action_code,
15913 u8 dialog_token, u16 status_code,
15914 u32 peer_capability, bool initiator,
15915 const u8 *buf, size_t len)
15916#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15917static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15918 struct net_device *dev,
15919 const u8 *peer, u8 action_code,
15920 u8 dialog_token, u16 status_code,
15921 u32 peer_capability, const u8 *buf,
15922 size_t len)
15923#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
15924static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15925 struct net_device *dev,
15926 u8 *peer, u8 action_code,
15927 u8 dialog_token,
15928 u16 status_code, u32 peer_capability,
15929 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015930#else
15931static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15932 u8 *peer, u8 action_code, u8 dialog_token,
15933 u16 status_code, const u8 *buf, size_t len)
15934#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015935#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015936{
15937 int ret;
15938
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015939 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015940#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015941 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15942 dialog_token, status_code,
15943 peer_capability, buf, len);
15944#else /* TDLS_MGMT_VERSION2 */
15945#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
15946 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15947 dialog_token, status_code,
15948 peer_capability, initiator,
15949 buf, len);
15950#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
15951 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15952 dialog_token, status_code,
15953 peer_capability, buf, len);
15954#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
15955 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15956 dialog_token, status_code,
15957 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015958#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015959 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15960 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015961#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015962#endif
15963 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015964
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015965 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015966}
Atul Mittal115287b2014-07-08 13:26:33 +053015967
15968int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015969#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15970 const u8 *peer,
15971#else
Atul Mittal115287b2014-07-08 13:26:33 +053015972 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015973#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015974 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053015975 cfg80211_exttdls_callback callback)
15976{
15977
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015978 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053015979 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015980 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053015981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15982 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
15983 __func__, MAC_ADDR_ARRAY(peer));
15984
15985 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15986 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15987
15988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015989 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15990 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15991 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015992 return -ENOTSUPP;
15993 }
15994
15995 /* To cater the requirement of establishing the TDLS link
15996 * irrespective of the data traffic , get an entry of TDLS peer.
15997 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015998 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015999 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
16000 if (pTdlsPeer == NULL) {
16001 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16002 "%s: peer " MAC_ADDRESS_STR " not existing",
16003 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016004 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016005 return -EINVAL;
16006 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016007 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016008
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053016009 /* check FW TDLS Off Channel capability */
16010 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053016011 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053016012 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016013 {
16014 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
16015 pTdlsPeer->peerParams.global_operating_class =
16016 tdls_peer_params->global_operating_class;
16017 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
16018 pTdlsPeer->peerParams.min_bandwidth_kbps =
16019 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016020 /* check configured channel is valid, non dfs and
16021 * not current operating channel */
16022 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
16023 tdls_peer_params->channel)) &&
16024 (pHddStaCtx) &&
16025 (tdls_peer_params->channel !=
16026 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016027 {
16028 pTdlsPeer->isOffChannelConfigured = TRUE;
16029 }
16030 else
16031 {
16032 pTdlsPeer->isOffChannelConfigured = FALSE;
16033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16034 "%s: Configured Tdls Off Channel is not valid", __func__);
16035
16036 }
16037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016038 "%s: tdls_off_channel %d isOffChannelConfigured %d "
16039 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016040 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016041 pTdlsPeer->isOffChannelConfigured,
16042 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016043 }
16044 else
16045 {
16046 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053016047 "%s: TDLS off channel FW capability %d, "
16048 "host capab %d or Invalid TDLS Peer Params", __func__,
16049 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
16050 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016051 }
16052
Atul Mittal115287b2014-07-08 13:26:33 +053016053 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
16054
16055 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16056 " %s TDLS Add Force Peer Failed",
16057 __func__);
16058 return -EINVAL;
16059 }
16060 /*EXT TDLS*/
16061
16062 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
16063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16064 " %s TDLS set callback Failed",
16065 __func__);
16066 return -EINVAL;
16067 }
16068
16069 return(0);
16070
16071}
16072
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016073int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
16074#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16075 const u8 *peer
16076#else
16077 u8 *peer
16078#endif
16079)
Atul Mittal115287b2014-07-08 13:26:33 +053016080{
16081
16082 hddTdlsPeer_t *pTdlsPeer;
16083 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16084 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16085 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
16086 __func__, MAC_ADDR_ARRAY(peer));
16087
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016088 if (0 != wlan_hdd_validate_context(pHddCtx)) {
16089 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
16090 return -EINVAL;
16091 }
16092
Atul Mittal115287b2014-07-08 13:26:33 +053016093 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
16094 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
16095
16096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016097 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
16098 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
16099 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053016100 return -ENOTSUPP;
16101 }
16102
16103
16104 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
16105
16106 if ( NULL == pTdlsPeer ) {
16107 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016108 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053016109 __func__, MAC_ADDR_ARRAY(peer));
16110 return -EINVAL;
16111 }
16112 else {
16113 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
16114 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016115 /* if channel switch is configured, reset
16116 the channel for this peer */
16117 if (TRUE == pTdlsPeer->isOffChannelConfigured)
16118 {
16119 pTdlsPeer->peerParams.channel = 0;
16120 pTdlsPeer->isOffChannelConfigured = FALSE;
16121 }
Atul Mittal115287b2014-07-08 13:26:33 +053016122 }
16123
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016124 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
16125 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053016126 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016127 }
Atul Mittal115287b2014-07-08 13:26:33 +053016128
16129 /*EXT TDLS*/
16130
16131 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
16132
16133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16134 " %s TDLS set callback Failed",
16135 __func__);
16136 return -EINVAL;
16137 }
16138 return(0);
16139
16140}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016141static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016142#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16143 const u8 *peer,
16144#else
16145 u8 *peer,
16146#endif
16147 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016148{
16149 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16150 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016151 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016152 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016153
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016154 ENTER();
16155
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016156 if (!pAdapter) {
16157 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16158 return -EINVAL;
16159 }
16160
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016161 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16162 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
16163 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016164 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016165 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070016167 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016168 return -EINVAL;
16169 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016170
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016171 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016172 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016173 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016174 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016175 }
16176
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016177
16178 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016179 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016180 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016181 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016182 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
16183 "Cannot process TDLS commands",
16184 pHddCtx->cfg_ini->fEnableTDLSSupport,
16185 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016186 return -ENOTSUPP;
16187 }
16188
16189 switch (oper) {
16190 case NL80211_TDLS_ENABLE_LINK:
16191 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016192 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016193 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016194 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053016195 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016196 tANI_U16 numCurrTdlsPeers = 0;
16197 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016198 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016199
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16201 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
16202 __func__, MAC_ADDR_ARRAY(peer));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016203 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016204 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016205 if ( NULL == pTdlsPeer ) {
16206 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16207 " (oper %d) not exsting. ignored",
16208 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16209 return -EINVAL;
16210 }
16211
16212 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16213 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16214 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16215 "NL80211_TDLS_ENABLE_LINK");
16216
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070016217 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
16218 {
16219 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
16220 MAC_ADDRESS_STR " failed",
16221 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
16222 return -EINVAL;
16223 }
16224
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016225 /* before starting tdls connection, set tdls
16226 * off channel established status to default value */
16227 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016228 /* TDLS Off Channel, Disable tdls channel switch,
16229 when there are more than one tdls link */
16230 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053016231 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016232 {
16233 /* get connected peer and send disable tdls off chan */
16234 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016235 if ((connPeer) &&
16236 (connPeer->isOffChannelSupported == TRUE) &&
16237 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016238 {
16239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16240 "%s: More then one peer connected, Disable "
16241 "TDLS channel switch", __func__);
16242
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016243 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016244 ret = sme_SendTdlsChanSwitchReq(
16245 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016246 pAdapter->sessionId,
16247 connPeer->peerMac,
16248 connPeer->peerParams.channel,
16249 TDLS_OFF_CHANNEL_BW_OFFSET,
16250 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016251 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016252 hddLog(VOS_TRACE_LEVEL_ERROR,
16253 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016254 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016255 }
16256 else
16257 {
16258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16259 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016260 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016261 "isOffChannelConfigured %d",
16262 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016263 (connPeer ? (connPeer->isOffChannelSupported)
16264 : -1),
16265 (connPeer ? (connPeer->isOffChannelConfigured)
16266 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016267 }
16268 }
16269
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016270 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016271 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016272 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053016273
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016274 if (0 != wlan_hdd_tdls_get_link_establish_params(
16275 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016276 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016277 return -EINVAL;
16278 }
16279 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016280
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016281 ret = sme_SendTdlsLinkEstablishParams(
16282 WLAN_HDD_GET_HAL_CTX(pAdapter),
16283 pAdapter->sessionId, peer,
16284 &tdlsLinkEstablishParams);
16285 if (ret != VOS_STATUS_SUCCESS) {
16286 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
16287 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016288 /* Send TDLS peer UAPSD capabilities to the firmware and
16289 * register with the TL on after the response for this operation
16290 * is received .
16291 */
16292 ret = wait_for_completion_interruptible_timeout(
16293 &pAdapter->tdls_link_establish_req_comp,
16294 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
16295 if (ret <= 0)
16296 {
16297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016298 FL("Link Establish Request Failed Status %ld"),
16299 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016300 return -EINVAL;
16301 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016302 }
Atul Mittal115287b2014-07-08 13:26:33 +053016303 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16304 eTDLS_LINK_CONNECTED,
16305 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016306 staDesc.ucSTAId = pTdlsPeer->staId;
16307 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016308 ret = WLANTL_UpdateTdlsSTAClient(
16309 pHddCtx->pvosContext,
16310 &staDesc);
16311 if (ret != VOS_STATUS_SUCCESS) {
16312 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
16313 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053016314
Gopichand Nakkala471708b2013-06-04 20:03:01 +053016315 /* Mark TDLS client Authenticated .*/
16316 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
16317 pTdlsPeer->staId,
16318 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016319 if (VOS_STATUS_SUCCESS == status)
16320 {
Hoonki Lee14621352013-04-16 17:51:19 -070016321 if (pTdlsPeer->is_responder == 0)
16322 {
16323 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053016324 tdlsConnInfo_t *tdlsInfo;
16325
16326 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
16327
16328 /* Initialize initiator wait callback */
16329 vos_timer_init(
16330 &pTdlsPeer->initiatorWaitTimeoutTimer,
16331 VOS_TIMER_TYPE_SW,
16332 wlan_hdd_tdls_initiator_wait_cb,
16333 tdlsInfo);
Hoonki Lee14621352013-04-16 17:51:19 -070016334
16335 wlan_hdd_tdls_timer_restart(pAdapter,
16336 &pTdlsPeer->initiatorWaitTimeoutTimer,
16337 WAIT_TIME_TDLS_INITIATOR);
16338 /* suspend initiator TX until it receives direct packet from the
16339 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016340 ret = WLANTL_SuspendDataTx(
16341 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16342 &staId, NULL);
16343 if (ret != VOS_STATUS_SUCCESS) {
16344 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
16345 }
Hoonki Lee14621352013-04-16 17:51:19 -070016346 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016347
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016348 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016349 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016350 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016351 suppChannelLen =
16352 tdlsLinkEstablishParams.supportedChannelsLen;
16353
16354 if ((suppChannelLen > 0) &&
16355 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
16356 {
16357 tANI_U8 suppPeerChannel = 0;
16358 int i = 0;
16359 for (i = 0U; i < suppChannelLen; i++)
16360 {
16361 suppPeerChannel =
16362 tdlsLinkEstablishParams.supportedChannels[i];
16363
16364 pTdlsPeer->isOffChannelSupported = FALSE;
16365 if (suppPeerChannel ==
16366 pTdlsPeer->peerParams.channel)
16367 {
16368 pTdlsPeer->isOffChannelSupported = TRUE;
16369 break;
16370 }
16371 }
16372 }
16373 else
16374 {
16375 pTdlsPeer->isOffChannelSupported = FALSE;
16376 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016377 }
16378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16379 "%s: TDLS channel switch request for channel "
16380 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016381 "%d isOffChannelSupported %d", __func__,
16382 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016383 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016384 suppChannelLen,
16385 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016386
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016387 /* TDLS Off Channel, Enable tdls channel switch,
16388 when their is only one tdls link and it supports */
16389 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16390 if ((numCurrTdlsPeers == 1) &&
16391 (TRUE == pTdlsPeer->isOffChannelSupported) &&
16392 (TRUE == pTdlsPeer->isOffChannelConfigured))
16393 {
16394 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16395 "%s: Send TDLS channel switch request for channel %d",
16396 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016397
16398 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016399 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
16400 pAdapter->sessionId,
16401 pTdlsPeer->peerMac,
16402 pTdlsPeer->peerParams.channel,
16403 TDLS_OFF_CHANNEL_BW_OFFSET,
16404 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016405 if (ret != VOS_STATUS_SUCCESS) {
16406 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
16407 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016408 }
16409 else
16410 {
16411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16412 "%s: TDLS channel switch request not sent"
16413 " numCurrTdlsPeers %d "
16414 "isOffChannelSupported %d "
16415 "isOffChannelConfigured %d",
16416 __func__, numCurrTdlsPeers,
16417 pTdlsPeer->isOffChannelSupported,
16418 pTdlsPeer->isOffChannelConfigured);
16419 }
16420
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016421 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016422 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016423
16424 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016425 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
16426 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016427 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016428 int ac;
16429 uint8 ucAc[4] = { WLANTL_AC_VO,
16430 WLANTL_AC_VI,
16431 WLANTL_AC_BK,
16432 WLANTL_AC_BE };
16433 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
16434 for(ac=0; ac < 4; ac++)
16435 {
16436 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16437 pTdlsPeer->staId, ucAc[ac],
16438 tlTid[ac], tlTid[ac], 0, 0,
16439 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016440 if (status != VOS_STATUS_SUCCESS) {
16441 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
16442 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016443 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016444 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016445 }
16446
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016447 }
16448 break;
16449 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080016450 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016451 tANI_U16 numCurrTdlsPeers = 0;
16452 hddTdlsPeer_t *connPeer = NULL;
16453
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16455 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
16456 __func__, MAC_ADDR_ARRAY(peer));
16457
Sunil Dutt41de4e22013-11-14 18:09:02 +053016458 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
16459
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016460
Sunil Dutt41de4e22013-11-14 18:09:02 +053016461 if ( NULL == pTdlsPeer ) {
16462 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16463 " (oper %d) not exsting. ignored",
16464 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16465 return -EINVAL;
16466 }
16467
16468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16469 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16470 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16471 "NL80211_TDLS_DISABLE_LINK");
16472
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016473 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080016474 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016475 long status;
16476
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016477 /* set tdls off channel status to false for this peer */
16478 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053016479 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16480 eTDLS_LINK_TEARING,
16481 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
16482 eTDLS_LINK_UNSPECIFIED:
16483 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016484 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
16485
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016486 status = sme_DeleteTdlsPeerSta(
16487 WLAN_HDD_GET_HAL_CTX(pAdapter),
16488 pAdapter->sessionId, peer );
16489 if (status != VOS_STATUS_SUCCESS) {
16490 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16491 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016492
16493 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
16494 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053016495 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053016496 eTDLS_LINK_IDLE,
16497 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016498 if (status <= 0)
16499 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016500 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16501 "%s: Del station failed status %ld",
16502 __func__, status);
16503 return -EPERM;
16504 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016505
16506 /* TDLS Off Channel, Enable tdls channel switch,
16507 when their is only one tdls link and it supports */
16508 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16509 if (numCurrTdlsPeers == 1)
16510 {
16511 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
16512 if ((connPeer) &&
16513 (connPeer->isOffChannelSupported == TRUE) &&
16514 (connPeer->isOffChannelConfigured == TRUE))
16515 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016516 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016517 status = sme_SendTdlsChanSwitchReq(
16518 WLAN_HDD_GET_HAL_CTX(pAdapter),
16519 pAdapter->sessionId,
16520 connPeer->peerMac,
16521 connPeer->peerParams.channel,
16522 TDLS_OFF_CHANNEL_BW_OFFSET,
16523 TDLS_CHANNEL_SWITCH_ENABLE);
16524 if (status != VOS_STATUS_SUCCESS) {
16525 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
16526 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016527 }
16528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16529 "%s: TDLS channel switch "
16530 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016531 "isOffChannelConfigured %d "
16532 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016533 __func__,
16534 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016535 (connPeer ? connPeer->isOffChannelConfigured : -1),
16536 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016537 }
16538 else
16539 {
16540 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16541 "%s: TDLS channel switch request not sent "
16542 "numCurrTdlsPeers %d ",
16543 __func__, numCurrTdlsPeers);
16544 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016545 }
16546 else
16547 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16549 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080016550 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016551 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016552 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016553 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016554 {
Atul Mittal115287b2014-07-08 13:26:33 +053016555 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016556
Atul Mittal115287b2014-07-08 13:26:33 +053016557 if (0 != status)
16558 {
16559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016560 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053016561 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016562 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053016563 break;
16564 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016565 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016566 {
Atul Mittal115287b2014-07-08 13:26:33 +053016567 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
16568 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016569 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053016570 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016571
Atul Mittal115287b2014-07-08 13:26:33 +053016572 if (0 != status)
16573 {
16574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016575 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053016576 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053016577 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053016578 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016579 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016580 case NL80211_TDLS_DISCOVERY_REQ:
16581 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016583 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016584 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016585 return -ENOTSUPP;
16586 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16588 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016589 return -ENOTSUPP;
16590 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016591
16592 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016593 return 0;
16594}
Chilam NG571c65a2013-01-19 12:27:36 +053016595
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016596static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016597#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16598 const u8 *peer,
16599#else
16600 u8 *peer,
16601#endif
16602 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016603{
16604 int ret;
16605
16606 vos_ssr_protect(__func__);
16607 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
16608 vos_ssr_unprotect(__func__);
16609
16610 return ret;
16611}
16612
Chilam NG571c65a2013-01-19 12:27:36 +053016613int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
16614 struct net_device *dev, u8 *peer)
16615{
Arif Hussaina7c8e412013-11-20 11:06:42 -080016616 hddLog(VOS_TRACE_LEVEL_INFO,
16617 "tdls send discover req: "MAC_ADDRESS_STR,
16618 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053016619
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016620#if TDLS_MGMT_VERSION2
16621 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16622 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16623#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016624#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
16625 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16626 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
16627#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16628 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16629 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16630#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
16631 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16632 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16633#else
Chilam NG571c65a2013-01-19 12:27:36 +053016634 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16635 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016636#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016637#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053016638}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016639#endif
16640
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016641#ifdef WLAN_FEATURE_GTK_OFFLOAD
16642/*
16643 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
16644 * Callback rountine called upon receiving response for
16645 * get offload info
16646 */
16647void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
16648 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
16649{
16650
16651 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016652 tANI_U8 tempReplayCounter[8];
16653 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016654
16655 ENTER();
16656
16657 if (NULL == pAdapter)
16658 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016660 "%s: HDD adapter is Null", __func__);
16661 return ;
16662 }
16663
16664 if (NULL == pGtkOffloadGetInfoRsp)
16665 {
16666 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16667 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
16668 return ;
16669 }
16670
16671 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
16672 {
16673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16674 "%s: wlan Failed to get replay counter value",
16675 __func__);
16676 return ;
16677 }
16678
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016679 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16680 /* Update replay counter */
16681 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
16682 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16683
16684 {
16685 /* changing from little to big endian since supplicant
16686 * works on big endian format
16687 */
16688 int i;
16689 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16690
16691 for (i = 0; i < 8; i++)
16692 {
16693 tempReplayCounter[7-i] = (tANI_U8)p[i];
16694 }
16695 }
16696
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016697 /* Update replay counter to NL */
16698 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016699 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016700}
16701
16702/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016703 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016704 * This function is used to offload GTK rekeying job to the firmware.
16705 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016706int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016707 struct cfg80211_gtk_rekey_data *data)
16708{
16709 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16710 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16711 hdd_station_ctx_t *pHddStaCtx;
16712 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016713 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016714 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016715 eHalStatus status = eHAL_STATUS_FAILURE;
16716
16717 ENTER();
16718
16719 if (NULL == pAdapter)
16720 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016722 "%s: HDD adapter is Null", __func__);
16723 return -ENODEV;
16724 }
16725
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016726 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16727 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
16728 pAdapter->sessionId, pAdapter->device_mode));
16729
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016730 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016731 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016732 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016733 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016734 }
16735
16736 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16737 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16738 if (NULL == hHal)
16739 {
16740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16741 "%s: HAL context is Null!!!", __func__);
16742 return -EAGAIN;
16743 }
16744
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016745 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
16746 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
16747 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
16748 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016749 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016750 {
16751 /* changing from big to little endian since driver
16752 * works on little endian format
16753 */
16754 tANI_U8 *p =
16755 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
16756 int i;
16757
16758 for (i = 0; i < 8; i++)
16759 {
16760 p[7-i] = data->replay_ctr[i];
16761 }
16762 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016763
16764 if (TRUE == pHddCtx->hdd_wlan_suspended)
16765 {
16766 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016767 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
16768 sizeof (tSirGtkOffloadParams));
16769 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016770 pAdapter->sessionId);
16771
16772 if (eHAL_STATUS_SUCCESS != status)
16773 {
16774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16775 "%s: sme_SetGTKOffload failed, returned %d",
16776 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016777
16778 /* Need to clear any trace of key value in the memory.
16779 * Thus zero out the memory even though it is local
16780 * variable.
16781 */
16782 vos_mem_zero(&hddGtkOffloadReqParams,
16783 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016784 return status;
16785 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16787 "%s: sme_SetGTKOffload successfull", __func__);
16788 }
16789 else
16790 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16792 "%s: wlan not suspended GTKOffload request is stored",
16793 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016794 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016795
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016796 /* Need to clear any trace of key value in the memory.
16797 * Thus zero out the memory even though it is local
16798 * variable.
16799 */
16800 vos_mem_zero(&hddGtkOffloadReqParams,
16801 sizeof(hddGtkOffloadReqParams));
16802
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016803 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016804 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016805}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016806
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016807int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
16808 struct cfg80211_gtk_rekey_data *data)
16809{
16810 int ret;
16811
16812 vos_ssr_protect(__func__);
16813 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
16814 vos_ssr_unprotect(__func__);
16815
16816 return ret;
16817}
16818#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016819/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016820 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016821 * This function is used to set access control policy
16822 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016823static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16824 struct net_device *dev,
16825 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016826{
16827 int i;
16828 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16829 hdd_hostapd_state_t *pHostapdState;
16830 tsap_Config_t *pConfig;
16831 v_CONTEXT_t pVosContext = NULL;
16832 hdd_context_t *pHddCtx;
16833 int status;
16834
16835 ENTER();
16836
16837 if (NULL == pAdapter)
16838 {
16839 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16840 "%s: HDD adapter is Null", __func__);
16841 return -ENODEV;
16842 }
16843
16844 if (NULL == params)
16845 {
16846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16847 "%s: params is Null", __func__);
16848 return -EINVAL;
16849 }
16850
16851 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16852 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016853 if (0 != status)
16854 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016855 return status;
16856 }
16857
16858 pVosContext = pHddCtx->pvosContext;
16859 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
16860
16861 if (NULL == pHostapdState)
16862 {
16863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16864 "%s: pHostapdState is Null", __func__);
16865 return -EINVAL;
16866 }
16867
16868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
16869 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016870 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16871 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
16872 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016873
16874 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
16875 {
16876 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
16877
16878 /* default value */
16879 pConfig->num_accept_mac = 0;
16880 pConfig->num_deny_mac = 0;
16881
16882 /**
16883 * access control policy
16884 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
16885 * listed in hostapd.deny file.
16886 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
16887 * listed in hostapd.accept file.
16888 */
16889 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
16890 {
16891 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
16892 }
16893 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
16894 {
16895 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
16896 }
16897 else
16898 {
16899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16900 "%s:Acl Policy : %d is not supported",
16901 __func__, params->acl_policy);
16902 return -ENOTSUPP;
16903 }
16904
16905 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
16906 {
16907 pConfig->num_accept_mac = params->n_acl_entries;
16908 for (i = 0; i < params->n_acl_entries; i++)
16909 {
16910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16911 "** Add ACL MAC entry %i in WhiletList :"
16912 MAC_ADDRESS_STR, i,
16913 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16914
16915 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
16916 sizeof(qcmacaddr));
16917 }
16918 }
16919 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
16920 {
16921 pConfig->num_deny_mac = params->n_acl_entries;
16922 for (i = 0; i < params->n_acl_entries; i++)
16923 {
16924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16925 "** Add ACL MAC entry %i in BlackList :"
16926 MAC_ADDRESS_STR, i,
16927 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16928
16929 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
16930 sizeof(qcmacaddr));
16931 }
16932 }
16933
16934 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
16935 {
16936 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16937 "%s: SAP Set Mac Acl fail", __func__);
16938 return -EINVAL;
16939 }
16940 }
16941 else
16942 {
16943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016944 "%s: Invalid device_mode = %s (%d)",
16945 __func__, hdd_device_modetoString(pAdapter->device_mode),
16946 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016947 return -EINVAL;
16948 }
16949
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016950 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016951 return 0;
16952}
16953
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016954static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16955 struct net_device *dev,
16956 const struct cfg80211_acl_data *params)
16957{
16958 int ret;
16959 vos_ssr_protect(__func__);
16960 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
16961 vos_ssr_unprotect(__func__);
16962
16963 return ret;
16964}
16965
Leo Chang9056f462013-08-01 19:21:11 -070016966#ifdef WLAN_NL80211_TESTMODE
16967#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070016968void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070016969(
16970 void *pAdapter,
16971 void *indCont
16972)
16973{
Leo Changd9df8aa2013-09-26 13:32:26 -070016974 tSirLPHBInd *lphbInd;
16975 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053016976 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070016977
16978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016979 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070016980
c_hpothu73f35e62014-04-18 13:40:08 +053016981 if (pAdapter == NULL)
16982 {
16983 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16984 "%s: pAdapter is NULL\n",__func__);
16985 return;
16986 }
16987
Leo Chang9056f462013-08-01 19:21:11 -070016988 if (NULL == indCont)
16989 {
16990 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016991 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070016992 return;
16993 }
16994
c_hpothu73f35e62014-04-18 13:40:08 +053016995 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070016996 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070016997 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053016998 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070016999 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070017000 GFP_ATOMIC);
17001 if (!skb)
17002 {
17003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17004 "LPHB timeout, NL buffer alloc fail");
17005 return;
17006 }
17007
Leo Changac3ba772013-10-07 09:47:04 -070017008 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070017009 {
17010 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17011 "WLAN_HDD_TM_ATTR_CMD put fail");
17012 goto nla_put_failure;
17013 }
Leo Changac3ba772013-10-07 09:47:04 -070017014 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070017015 {
17016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17017 "WLAN_HDD_TM_ATTR_TYPE put fail");
17018 goto nla_put_failure;
17019 }
Leo Changac3ba772013-10-07 09:47:04 -070017020 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070017021 sizeof(tSirLPHBInd), lphbInd))
17022 {
17023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17024 "WLAN_HDD_TM_ATTR_DATA put fail");
17025 goto nla_put_failure;
17026 }
Leo Chang9056f462013-08-01 19:21:11 -070017027 cfg80211_testmode_event(skb, GFP_ATOMIC);
17028 return;
17029
17030nla_put_failure:
17031 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17032 "NLA Put fail");
17033 kfree_skb(skb);
17034
17035 return;
17036}
17037#endif /* FEATURE_WLAN_LPHB */
17038
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017039static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070017040{
17041 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
17042 int err = 0;
17043#ifdef FEATURE_WLAN_LPHB
17044 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070017045 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017046
17047 ENTER();
17048
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017049 err = wlan_hdd_validate_context(pHddCtx);
17050 if (0 != err)
17051 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017052 return err;
17053 }
Leo Chang9056f462013-08-01 19:21:11 -070017054#endif /* FEATURE_WLAN_LPHB */
17055
17056 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
17057 if (err)
17058 {
17059 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17060 "%s Testmode INV ATTR", __func__);
17061 return err;
17062 }
17063
17064 if (!tb[WLAN_HDD_TM_ATTR_CMD])
17065 {
17066 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17067 "%s Testmode INV CMD", __func__);
17068 return -EINVAL;
17069 }
17070
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017071 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17072 TRACE_CODE_HDD_CFG80211_TESTMODE,
17073 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070017074 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
17075 {
17076#ifdef FEATURE_WLAN_LPHB
17077 /* Low Power Heartbeat configuration request */
17078 case WLAN_HDD_TM_CMD_WLAN_HB:
17079 {
17080 int buf_len;
17081 void *buf;
17082 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080017083 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070017084
17085 if (!tb[WLAN_HDD_TM_ATTR_DATA])
17086 {
17087 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17088 "%s Testmode INV DATA", __func__);
17089 return -EINVAL;
17090 }
17091
17092 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
17093 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080017094
17095 hb_params_temp =(tSirLPHBReq *)buf;
17096 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
17097 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
17098 return -EINVAL;
17099
Leo Chang9056f462013-08-01 19:21:11 -070017100 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
17101 if (NULL == hb_params)
17102 {
17103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17104 "%s Request Buffer Alloc Fail", __func__);
17105 return -EINVAL;
17106 }
17107
17108 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070017109 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
17110 hb_params,
17111 wlan_hdd_cfg80211_lphb_ind_handler);
17112 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070017113 {
Leo Changd9df8aa2013-09-26 13:32:26 -070017114 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17115 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070017116 vos_mem_free(hb_params);
17117 }
Leo Chang9056f462013-08-01 19:21:11 -070017118 return 0;
17119 }
17120#endif /* FEATURE_WLAN_LPHB */
17121 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17123 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070017124 return -EOPNOTSUPP;
17125 }
17126
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017127 EXIT();
17128 return err;
Leo Chang9056f462013-08-01 19:21:11 -070017129}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017130
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053017131static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
17132#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
17133 struct wireless_dev *wdev,
17134#endif
17135 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017136{
17137 int ret;
17138
17139 vos_ssr_protect(__func__);
17140 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
17141 vos_ssr_unprotect(__func__);
17142
17143 return ret;
17144}
Leo Chang9056f462013-08-01 19:21:11 -070017145#endif /* CONFIG_NL80211_TESTMODE */
17146
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017147static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017148 struct net_device *dev,
17149 int idx, struct survey_info *survey)
17150{
17151 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17152 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053017153 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017154 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053017155 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017156 v_S7_t snr,rssi;
17157 int status, i, j, filled = 0;
17158
17159 ENTER();
17160
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017161 if (NULL == pAdapter)
17162 {
17163 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17164 "%s: HDD adapter is Null", __func__);
17165 return -ENODEV;
17166 }
17167
17168 if (NULL == wiphy)
17169 {
17170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17171 "%s: wiphy is Null", __func__);
17172 return -ENODEV;
17173 }
17174
17175 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17176 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017177 if (0 != status)
17178 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017179 return status;
17180 }
17181
Mihir Sheted9072e02013-08-21 17:02:29 +053017182 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17183
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017184 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053017185 0 != pAdapter->survey_idx ||
17186 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017187 {
17188 /* The survey dump ops when implemented completely is expected to
17189 * return a survey of all channels and the ops is called by the
17190 * kernel with incremental values of the argument 'idx' till it
17191 * returns -ENONET. But we can only support the survey for the
17192 * operating channel for now. survey_idx is used to track
17193 * that the ops is called only once and then return -ENONET for
17194 * the next iteration
17195 */
17196 pAdapter->survey_idx = 0;
17197 return -ENONET;
17198 }
17199
Mukul Sharma9d5233b2015-06-11 20:28:20 +053017200 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17201 {
17202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17203 "%s: Roaming in progress, hence return ", __func__);
17204 return -ENONET;
17205 }
17206
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017207 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17208
17209 wlan_hdd_get_snr(pAdapter, &snr);
17210 wlan_hdd_get_rssi(pAdapter, &rssi);
17211
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017212 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17213 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
17214 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017215 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
17216 hdd_wlan_get_freq(channel, &freq);
17217
17218
17219 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
17220 {
17221 if (NULL == wiphy->bands[i])
17222 {
17223 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
17224 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
17225 continue;
17226 }
17227
17228 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
17229 {
17230 struct ieee80211_supported_band *band = wiphy->bands[i];
17231
17232 if (band->channels[j].center_freq == (v_U16_t)freq)
17233 {
17234 survey->channel = &band->channels[j];
17235 /* The Rx BDs contain SNR values in dB for the received frames
17236 * while the supplicant expects noise. So we calculate and
17237 * return the value of noise (dBm)
17238 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
17239 */
17240 survey->noise = rssi - snr;
17241 survey->filled = SURVEY_INFO_NOISE_DBM;
17242 filled = 1;
17243 }
17244 }
17245 }
17246
17247 if (filled)
17248 pAdapter->survey_idx = 1;
17249 else
17250 {
17251 pAdapter->survey_idx = 0;
17252 return -ENONET;
17253 }
17254
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017255 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017256 return 0;
17257}
17258
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017259static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
17260 struct net_device *dev,
17261 int idx, struct survey_info *survey)
17262{
17263 int ret;
17264
17265 vos_ssr_protect(__func__);
17266 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
17267 vos_ssr_unprotect(__func__);
17268
17269 return ret;
17270}
17271
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017272/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017273 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017274 * this is called when cfg80211 driver resume
17275 * driver updates latest sched_scan scan result(if any) to cfg80211 database
17276 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017277int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017278{
17279 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17280 hdd_adapter_t *pAdapter;
17281 hdd_adapter_list_node_t *pAdapterNode, *pNext;
17282 VOS_STATUS status = VOS_STATUS_SUCCESS;
17283
17284 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017285
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017286 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017287 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017288 return 0;
17289 }
17290
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017291 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
17292 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017293 spin_lock(&pHddCtx->schedScan_lock);
17294 pHddCtx->isWiphySuspended = FALSE;
17295 if (TRUE != pHddCtx->isSchedScanUpdatePending)
17296 {
17297 spin_unlock(&pHddCtx->schedScan_lock);
17298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17299 "%s: Return resume is not due to PNO indication", __func__);
17300 return 0;
17301 }
17302 // Reset flag to avoid updatating cfg80211 data old results again
17303 pHddCtx->isSchedScanUpdatePending = FALSE;
17304 spin_unlock(&pHddCtx->schedScan_lock);
17305
17306 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
17307
17308 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
17309 {
17310 pAdapter = pAdapterNode->pAdapter;
17311 if ( (NULL != pAdapter) &&
17312 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
17313 {
17314 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017315 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017316 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17317 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017318 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017319 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017320 {
17321 /* Acquire wakelock to handle the case where APP's tries to
17322 * suspend immediately after updating the scan results. Whis
17323 * results in app's is in suspended state and not able to
17324 * process the connect request to AP
17325 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053017326 hdd_prevent_suspend_timeout(2000,
17327 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017328 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017329 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017330
17331 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17332 "%s : cfg80211 scan result database updated", __func__);
17333
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017334 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017335 return 0;
17336
17337 }
17338 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17339 pAdapterNode = pNext;
17340 }
17341
17342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17343 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017344 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017345 return 0;
17346}
17347
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017348int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
17349{
17350 int ret;
17351
17352 vos_ssr_protect(__func__);
17353 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
17354 vos_ssr_unprotect(__func__);
17355
17356 return ret;
17357}
17358
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017359/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017360 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017361 * this is called when cfg80211 driver suspends
17362 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017363int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017364 struct cfg80211_wowlan *wow)
17365{
17366 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017367 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017368
17369 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017370
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017371 ret = wlan_hdd_validate_context(pHddCtx);
17372 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017373 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017374 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017375 }
17376
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017377
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017378 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17379 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
17380 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017381 pHddCtx->isWiphySuspended = TRUE;
17382
17383 EXIT();
17384
17385 return 0;
17386}
17387
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017388int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
17389 struct cfg80211_wowlan *wow)
17390{
17391 int ret;
17392
17393 vos_ssr_protect(__func__);
17394 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
17395 vos_ssr_unprotect(__func__);
17396
17397 return ret;
17398}
Jeff Johnson295189b2012-06-20 16:38:30 -070017399/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017400static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070017401{
17402 .add_virtual_intf = wlan_hdd_add_virtual_intf,
17403 .del_virtual_intf = wlan_hdd_del_virtual_intf,
17404 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
17405 .change_station = wlan_hdd_change_station,
17406#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
17407 .add_beacon = wlan_hdd_cfg80211_add_beacon,
17408 .del_beacon = wlan_hdd_cfg80211_del_beacon,
17409 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017410#else
17411 .start_ap = wlan_hdd_cfg80211_start_ap,
17412 .change_beacon = wlan_hdd_cfg80211_change_beacon,
17413 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070017414#endif
17415 .change_bss = wlan_hdd_cfg80211_change_bss,
17416 .add_key = wlan_hdd_cfg80211_add_key,
17417 .get_key = wlan_hdd_cfg80211_get_key,
17418 .del_key = wlan_hdd_cfg80211_del_key,
17419 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017420#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070017421 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017422#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017423 .scan = wlan_hdd_cfg80211_scan,
17424 .connect = wlan_hdd_cfg80211_connect,
17425 .disconnect = wlan_hdd_cfg80211_disconnect,
17426 .join_ibss = wlan_hdd_cfg80211_join_ibss,
17427 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
17428 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
17429 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
17430 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070017431 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
17432 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053017433 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070017434#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17435 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
17436 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
17437 .set_txq_params = wlan_hdd_set_txq_params,
17438#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017439 .get_station = wlan_hdd_cfg80211_get_station,
17440 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
17441 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017442 .add_station = wlan_hdd_cfg80211_add_station,
17443#ifdef FEATURE_WLAN_LFR
17444 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
17445 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
17446 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
17447#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017448#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
17449 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
17450#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017451#ifdef FEATURE_WLAN_TDLS
17452 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
17453 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
17454#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017455#ifdef WLAN_FEATURE_GTK_OFFLOAD
17456 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
17457#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017458#ifdef FEATURE_WLAN_SCAN_PNO
17459 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
17460 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
17461#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017462 .resume = wlan_hdd_cfg80211_resume_wlan,
17463 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017464 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070017465#ifdef WLAN_NL80211_TESTMODE
17466 .testmode_cmd = wlan_hdd_cfg80211_testmode,
17467#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017468 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070017469};
17470