blob: c1369960693ff982248d6a8f78c934a9706e9778 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#ifdef FEATURE_WLAN_TDLS
94#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053095#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053096#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080097#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053098#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070099#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700100
101#define g_mode_rates_size (12)
102#define a_mode_rates_size (8)
103#define FREQ_BASE_80211G (2407)
104#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700105#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530106#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700107#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800108 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700109
110#define HDD2GHZCHAN(freq, chan, flag) { \
111 .band = IEEE80211_BAND_2GHZ, \
112 .center_freq = (freq), \
113 .hw_value = (chan),\
114 .flags = (flag), \
115 .max_antenna_gain = 0 ,\
116 .max_power = 30, \
117}
118
119#define HDD5GHZCHAN(freq, chan, flag) { \
120 .band = IEEE80211_BAND_5GHZ, \
121 .center_freq = (freq), \
122 .hw_value = (chan),\
123 .flags = (flag), \
124 .max_antenna_gain = 0 ,\
125 .max_power = 30, \
126}
127
128#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
129{\
130 .bitrate = rate, \
131 .hw_value = rate_id, \
132 .flags = flag, \
133}
134
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530135#ifdef WLAN_FEATURE_VOWIFI_11R
136#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
137#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
138#endif
139
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530140#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530141#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530142
Sunil Duttc69bccb2014-05-26 21:30:20 +0530143#ifdef WLAN_FEATURE_LINK_LAYER_STATS
144/*
145 * Used to allocate the size of 4096 for the link layer stats.
146 * The size of 4096 is considered assuming that all data per
147 * respective event fit with in the limit.Please take a call
148 * on the limit based on the data requirements on link layer
149 * statistics.
150 */
151#define LL_STATS_EVENT_BUF_SIZE 4096
152#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530153#ifdef WLAN_FEATURE_EXTSCAN
154/*
155 * Used to allocate the size of 4096 for the EXTScan NL data.
156 * The size of 4096 is considered assuming that all data per
157 * respective event fit with in the limit.Please take a call
158 * on the limit based on the data requirements.
159 */
160
161#define EXTSCAN_EVENT_BUF_SIZE 4096
162#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
163#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530164
Atul Mittal115287b2014-07-08 13:26:33 +0530165/*EXT TDLS*/
166/*
167 * Used to allocate the size of 4096 for the TDLS.
168 * The size of 4096 is considered assuming that all data per
169 * respective event fit with in the limit.Please take a call
170 * on the limit based on the data requirements on link layer
171 * statistics.
172 */
173#define EXTTDLS_EVENT_BUF_SIZE 4096
174
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530175static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700176{
177 WLAN_CIPHER_SUITE_WEP40,
178 WLAN_CIPHER_SUITE_WEP104,
179 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800180#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700181#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
182 WLAN_CIPHER_SUITE_KRK,
183 WLAN_CIPHER_SUITE_CCMP,
184#else
185 WLAN_CIPHER_SUITE_CCMP,
186#endif
187#ifdef FEATURE_WLAN_WAPI
188 WLAN_CIPHER_SUITE_SMS4,
189#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700190#ifdef WLAN_FEATURE_11W
191 WLAN_CIPHER_SUITE_AES_CMAC,
192#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700193};
194
195static inline int is_broadcast_ether_addr(const u8 *addr)
196{
197 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
198 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
199}
200
201static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530202{
Jeff Johnson295189b2012-06-20 16:38:30 -0700203 HDD2GHZCHAN(2412, 1, 0) ,
204 HDD2GHZCHAN(2417, 2, 0) ,
205 HDD2GHZCHAN(2422, 3, 0) ,
206 HDD2GHZCHAN(2427, 4, 0) ,
207 HDD2GHZCHAN(2432, 5, 0) ,
208 HDD2GHZCHAN(2437, 6, 0) ,
209 HDD2GHZCHAN(2442, 7, 0) ,
210 HDD2GHZCHAN(2447, 8, 0) ,
211 HDD2GHZCHAN(2452, 9, 0) ,
212 HDD2GHZCHAN(2457, 10, 0) ,
213 HDD2GHZCHAN(2462, 11, 0) ,
214 HDD2GHZCHAN(2467, 12, 0) ,
215 HDD2GHZCHAN(2472, 13, 0) ,
216 HDD2GHZCHAN(2484, 14, 0) ,
217};
218
Jeff Johnson295189b2012-06-20 16:38:30 -0700219static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
220{
221 HDD2GHZCHAN(2412, 1, 0) ,
222 HDD2GHZCHAN(2437, 6, 0) ,
223 HDD2GHZCHAN(2462, 11, 0) ,
224};
Jeff Johnson295189b2012-06-20 16:38:30 -0700225
226static struct ieee80211_channel hdd_channels_5_GHZ[] =
227{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700228 HDD5GHZCHAN(4920, 240, 0) ,
229 HDD5GHZCHAN(4940, 244, 0) ,
230 HDD5GHZCHAN(4960, 248, 0) ,
231 HDD5GHZCHAN(4980, 252, 0) ,
232 HDD5GHZCHAN(5040, 208, 0) ,
233 HDD5GHZCHAN(5060, 212, 0) ,
234 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700235 HDD5GHZCHAN(5180, 36, 0) ,
236 HDD5GHZCHAN(5200, 40, 0) ,
237 HDD5GHZCHAN(5220, 44, 0) ,
238 HDD5GHZCHAN(5240, 48, 0) ,
239 HDD5GHZCHAN(5260, 52, 0) ,
240 HDD5GHZCHAN(5280, 56, 0) ,
241 HDD5GHZCHAN(5300, 60, 0) ,
242 HDD5GHZCHAN(5320, 64, 0) ,
243 HDD5GHZCHAN(5500,100, 0) ,
244 HDD5GHZCHAN(5520,104, 0) ,
245 HDD5GHZCHAN(5540,108, 0) ,
246 HDD5GHZCHAN(5560,112, 0) ,
247 HDD5GHZCHAN(5580,116, 0) ,
248 HDD5GHZCHAN(5600,120, 0) ,
249 HDD5GHZCHAN(5620,124, 0) ,
250 HDD5GHZCHAN(5640,128, 0) ,
251 HDD5GHZCHAN(5660,132, 0) ,
252 HDD5GHZCHAN(5680,136, 0) ,
253 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800254#ifdef FEATURE_WLAN_CH144
255 HDD5GHZCHAN(5720,144, 0) ,
256#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700257 HDD5GHZCHAN(5745,149, 0) ,
258 HDD5GHZCHAN(5765,153, 0) ,
259 HDD5GHZCHAN(5785,157, 0) ,
260 HDD5GHZCHAN(5805,161, 0) ,
261 HDD5GHZCHAN(5825,165, 0) ,
262};
263
264static struct ieee80211_rate g_mode_rates[] =
265{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530266 HDD_G_MODE_RATETAB(10, 0x1, 0),
267 HDD_G_MODE_RATETAB(20, 0x2, 0),
268 HDD_G_MODE_RATETAB(55, 0x4, 0),
269 HDD_G_MODE_RATETAB(110, 0x8, 0),
270 HDD_G_MODE_RATETAB(60, 0x10, 0),
271 HDD_G_MODE_RATETAB(90, 0x20, 0),
272 HDD_G_MODE_RATETAB(120, 0x40, 0),
273 HDD_G_MODE_RATETAB(180, 0x80, 0),
274 HDD_G_MODE_RATETAB(240, 0x100, 0),
275 HDD_G_MODE_RATETAB(360, 0x200, 0),
276 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700277 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530278};
Jeff Johnson295189b2012-06-20 16:38:30 -0700279
280static struct ieee80211_rate a_mode_rates[] =
281{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282 HDD_G_MODE_RATETAB(60, 0x10, 0),
283 HDD_G_MODE_RATETAB(90, 0x20, 0),
284 HDD_G_MODE_RATETAB(120, 0x40, 0),
285 HDD_G_MODE_RATETAB(180, 0x80, 0),
286 HDD_G_MODE_RATETAB(240, 0x100, 0),
287 HDD_G_MODE_RATETAB(360, 0x200, 0),
288 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700289 HDD_G_MODE_RATETAB(540, 0x800, 0),
290};
291
292static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
293{
294 .channels = hdd_channels_2_4_GHZ,
295 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
296 .band = IEEE80211_BAND_2GHZ,
297 .bitrates = g_mode_rates,
298 .n_bitrates = g_mode_rates_size,
299 .ht_cap.ht_supported = 1,
300 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
301 | IEEE80211_HT_CAP_GRN_FLD
302 | IEEE80211_HT_CAP_DSSSCCK40
303 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
304 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
305 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
306 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
307 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
308 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
309};
310
Jeff Johnson295189b2012-06-20 16:38:30 -0700311static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
312{
313 .channels = hdd_social_channels_2_4_GHZ,
314 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
315 .band = IEEE80211_BAND_2GHZ,
316 .bitrates = g_mode_rates,
317 .n_bitrates = g_mode_rates_size,
318 .ht_cap.ht_supported = 1,
319 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
320 | IEEE80211_HT_CAP_GRN_FLD
321 | IEEE80211_HT_CAP_DSSSCCK40
322 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
323 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
324 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
325 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
326 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
327 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
328};
Jeff Johnson295189b2012-06-20 16:38:30 -0700329
330static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
331{
332 .channels = hdd_channels_5_GHZ,
333 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
334 .band = IEEE80211_BAND_5GHZ,
335 .bitrates = a_mode_rates,
336 .n_bitrates = a_mode_rates_size,
337 .ht_cap.ht_supported = 1,
338 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
339 | IEEE80211_HT_CAP_GRN_FLD
340 | IEEE80211_HT_CAP_DSSSCCK40
341 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
342 | IEEE80211_HT_CAP_SGI_40
343 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
344 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
345 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
346 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
347 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
348 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
349};
350
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530351/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700352 TX/RX direction for each kind of interface */
353static const struct ieee80211_txrx_stypes
354wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
355 [NL80211_IFTYPE_STATION] = {
356 .tx = 0xffff,
357 .rx = BIT(SIR_MAC_MGMT_ACTION) |
358 BIT(SIR_MAC_MGMT_PROBE_REQ),
359 },
360 [NL80211_IFTYPE_AP] = {
361 .tx = 0xffff,
362 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
363 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
364 BIT(SIR_MAC_MGMT_PROBE_REQ) |
365 BIT(SIR_MAC_MGMT_DISASSOC) |
366 BIT(SIR_MAC_MGMT_AUTH) |
367 BIT(SIR_MAC_MGMT_DEAUTH) |
368 BIT(SIR_MAC_MGMT_ACTION),
369 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700370 [NL80211_IFTYPE_ADHOC] = {
371 .tx = 0xffff,
372 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
373 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_PROBE_REQ) |
375 BIT(SIR_MAC_MGMT_DISASSOC) |
376 BIT(SIR_MAC_MGMT_AUTH) |
377 BIT(SIR_MAC_MGMT_DEAUTH) |
378 BIT(SIR_MAC_MGMT_ACTION),
379 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700380 [NL80211_IFTYPE_P2P_CLIENT] = {
381 .tx = 0xffff,
382 .rx = BIT(SIR_MAC_MGMT_ACTION) |
383 BIT(SIR_MAC_MGMT_PROBE_REQ),
384 },
385 [NL80211_IFTYPE_P2P_GO] = {
386 /* This is also same as for SoftAP */
387 .tx = 0xffff,
388 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
389 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
390 BIT(SIR_MAC_MGMT_PROBE_REQ) |
391 BIT(SIR_MAC_MGMT_DISASSOC) |
392 BIT(SIR_MAC_MGMT_AUTH) |
393 BIT(SIR_MAC_MGMT_DEAUTH) |
394 BIT(SIR_MAC_MGMT_ACTION),
395 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700396};
397
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800398#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800399static const struct ieee80211_iface_limit
400wlan_hdd_iface_limit[] = {
401 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800402 /* max = 3 ; Our driver create two interfaces during driver init
403 * wlan0 and p2p0 interfaces. p2p0 is considered as station
404 * interface until a group is formed. In JB architecture, once the
405 * group is formed, interface type of p2p0 is changed to P2P GO or
406 * Client.
407 * When supplicant remove the group, it first issue a set interface
408 * cmd to change the mode back to Station. In JB this works fine as
409 * we advertize two station type interface during driver init.
410 * Some vendors create separate interface for P2P GO/Client,
411 * after group formation(Third one). But while group remove
412 * supplicant first tries to change the mode(3rd interface) to STATION
413 * But as we advertized only two sta type interfaces nl80211 was
414 * returning error for the third one which was leading to failure in
415 * delete interface. Ideally while removing the group, supplicant
416 * should not try to change the 3rd interface mode to Station type.
417 * Till we get a fix in wpa_supplicant, we advertize max STA
418 * interface type to 3
419 */
420 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800421 .types = BIT(NL80211_IFTYPE_STATION),
422 },
423 {
424 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700425 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800426 },
427 {
428 .max = 1,
429 .types = BIT(NL80211_IFTYPE_P2P_GO) |
430 BIT(NL80211_IFTYPE_P2P_CLIENT),
431 },
432};
433
434/* By default, only single channel concurrency is allowed */
435static struct ieee80211_iface_combination
436wlan_hdd_iface_combination = {
437 .limits = wlan_hdd_iface_limit,
438 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800439 /*
440 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
441 * and p2p0 interfaces during driver init
442 * Some vendors create separate interface for P2P operations.
443 * wlan0: STA interface
444 * p2p0: P2P Device interface, action frames goes
445 * through this interface.
446 * p2p-xx: P2P interface, After GO negotiation this interface is
447 * created for p2p operations(GO/CLIENT interface).
448 */
449 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800450 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
451 .beacon_int_infra_match = false,
452};
453#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800454
Jeff Johnson295189b2012-06-20 16:38:30 -0700455static struct cfg80211_ops wlan_hdd_cfg80211_ops;
456
457/* Data rate 100KBPS based on IE Index */
458struct index_data_rate_type
459{
460 v_U8_t beacon_rate_index;
461 v_U16_t supported_rate[4];
462};
463
464/* 11B, 11G Rate table include Basic rate and Extended rate
465 The IDX field is the rate index
466 The HI field is the rate when RSSI is strong or being ignored
467 (in this case we report actual rate)
468 The MID field is the rate when RSSI is moderate
469 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
470 The LO field is the rate when RSSI is low
471 (in this case we don't report rates, actual current rate used)
472 */
473static const struct
474{
475 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700476 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700477} supported_data_rate[] =
478{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700479/* IDX HI HM LM LO (RSSI-based index */
480 {2, { 10, 10, 10, 0}},
481 {4, { 20, 20, 10, 0}},
482 {11, { 55, 20, 10, 0}},
483 {12, { 60, 55, 20, 0}},
484 {18, { 90, 55, 20, 0}},
485 {22, {110, 55, 20, 0}},
486 {24, {120, 90, 60, 0}},
487 {36, {180, 120, 60, 0}},
488 {44, {220, 180, 60, 0}},
489 {48, {240, 180, 90, 0}},
490 {66, {330, 180, 90, 0}},
491 {72, {360, 240, 90, 0}},
492 {96, {480, 240, 120, 0}},
493 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700494};
495
496/* MCS Based rate table */
497static struct index_data_rate_type supported_mcs_rate[] =
498{
499/* MCS L20 L40 S20 S40 */
500 {0, {65, 135, 72, 150}},
501 {1, {130, 270, 144, 300}},
502 {2, {195, 405, 217, 450}},
503 {3, {260, 540, 289, 600}},
504 {4, {390, 810, 433, 900}},
505 {5, {520, 1080, 578, 1200}},
506 {6, {585, 1215, 650, 1350}},
507 {7, {650, 1350, 722, 1500}}
508};
509
Leo Chang6f8870f2013-03-26 18:11:36 -0700510#ifdef WLAN_FEATURE_11AC
511
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530512#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700513
514struct index_vht_data_rate_type
515{
516 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530517 v_U16_t supported_VHT80_rate[2];
518 v_U16_t supported_VHT40_rate[2];
519 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700520};
521
522typedef enum
523{
524 DATA_RATE_11AC_MAX_MCS_7,
525 DATA_RATE_11AC_MAX_MCS_8,
526 DATA_RATE_11AC_MAX_MCS_9,
527 DATA_RATE_11AC_MAX_MCS_NA
528} eDataRate11ACMaxMcs;
529
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530530/* SSID broadcast type */
531typedef enum eSSIDBcastType
532{
533 eBCAST_UNKNOWN = 0,
534 eBCAST_NORMAL = 1,
535 eBCAST_HIDDEN = 2,
536} tSSIDBcastType;
537
Leo Chang6f8870f2013-03-26 18:11:36 -0700538/* MCS Based VHT rate table */
539static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
540{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530541/* MCS L80 S80 L40 S40 L20 S40*/
542 {0, {293, 325}, {135, 150}, {65, 72}},
543 {1, {585, 650}, {270, 300}, {130, 144}},
544 {2, {878, 975}, {405, 450}, {195, 217}},
545 {3, {1170, 1300}, {540, 600}, {260, 289}},
546 {4, {1755, 1950}, {810, 900}, {390, 433}},
547 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
548 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
549 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
550 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
551 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700552};
553#endif /* WLAN_FEATURE_11AC */
554
c_hpothu79aab322014-07-14 21:11:01 +0530555/*array index points to MCS and array value points respective rssi*/
556static int rssiMcsTbl[][10] =
557{
558/*MCS 0 1 2 3 4 5 6 7 8 9*/
559 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
560 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
561 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
562};
563
Jeff Johnson295189b2012-06-20 16:38:30 -0700564extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530565#ifdef FEATURE_WLAN_SCAN_PNO
566static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
567#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700568
Leo Chang9056f462013-08-01 19:21:11 -0700569#ifdef WLAN_NL80211_TESTMODE
570enum wlan_hdd_tm_attr
571{
572 WLAN_HDD_TM_ATTR_INVALID = 0,
573 WLAN_HDD_TM_ATTR_CMD = 1,
574 WLAN_HDD_TM_ATTR_DATA = 2,
575 WLAN_HDD_TM_ATTR_TYPE = 3,
576 /* keep last */
577 WLAN_HDD_TM_ATTR_AFTER_LAST,
578 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
579};
580
581enum wlan_hdd_tm_cmd
582{
583 WLAN_HDD_TM_CMD_WLAN_HB = 1,
584};
585
586#define WLAN_HDD_TM_DATA_MAX_LEN 5000
587
588static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
589{
590 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
591 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
592 .len = WLAN_HDD_TM_DATA_MAX_LEN },
593};
594#endif /* WLAN_NL80211_TESTMODE */
595
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800596#ifdef FEATURE_WLAN_CH_AVOID
597/*
598 * FUNCTION: wlan_hdd_send_avoid_freq_event
599 * This is called when wlan driver needs to send vendor specific
600 * avoid frequency range event to userspace
601 */
602int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
603 tHddAvoidFreqList *pAvoidFreqList)
604{
605 struct sk_buff *vendor_event;
606
607 ENTER();
608
609 if (!pHddCtx)
610 {
611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
612 "%s: HDD context is null", __func__);
613 return -1;
614 }
615
616 if (!pAvoidFreqList)
617 {
618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
619 "%s: pAvoidFreqList is null", __func__);
620 return -1;
621 }
622
623 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
624 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530625 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800626 GFP_KERNEL);
627 if (!vendor_event)
628 {
629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
630 "%s: cfg80211_vendor_event_alloc failed", __func__);
631 return -1;
632 }
633
634 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
635 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
636
637 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
638
639 EXIT();
640 return 0;
641}
642#endif /* FEATURE_WLAN_CH_AVOID */
643
Sunil Duttc69bccb2014-05-26 21:30:20 +0530644#ifdef WLAN_FEATURE_LINK_LAYER_STATS
645
646static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
647 struct sk_buff *vendor_event)
648{
649 if (nla_put_u8(vendor_event,
650 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
651 stats->rate.preamble) ||
652 nla_put_u8(vendor_event,
653 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
654 stats->rate.nss) ||
655 nla_put_u8(vendor_event,
656 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
657 stats->rate.bw) ||
658 nla_put_u8(vendor_event,
659 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
660 stats->rate.rateMcsIdx) ||
661 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
662 stats->rate.bitrate ) ||
663 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
664 stats->txMpdu ) ||
665 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
666 stats->rxMpdu ) ||
667 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
668 stats->mpduLost ) ||
669 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
670 stats->retries) ||
671 nla_put_u32(vendor_event,
672 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
673 stats->retriesShort ) ||
674 nla_put_u32(vendor_event,
675 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
676 stats->retriesLong))
677 {
678 hddLog(VOS_TRACE_LEVEL_ERROR,
679 FL("QCA_WLAN_VENDOR_ATTR put fail"));
680 return FALSE;
681 }
682 return TRUE;
683}
684
685static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
686 struct sk_buff *vendor_event)
687{
688 u32 i = 0;
689 struct nlattr *rateInfo;
690 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
691 stats->type) ||
692 nla_put(vendor_event,
693 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
694 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
695 nla_put_u32(vendor_event,
696 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
697 stats->capabilities) ||
698 nla_put_u32(vendor_event,
699 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
700 stats->numRate))
701 {
702 hddLog(VOS_TRACE_LEVEL_ERROR,
703 FL("QCA_WLAN_VENDOR_ATTR put fail"));
704 goto error;
705 }
706
707 rateInfo = nla_nest_start(vendor_event,
708 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530709 if(!rateInfo)
710 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530711 for (i = 0; i < stats->numRate; i++)
712 {
713 struct nlattr *rates;
714 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
715 stats->rateStats +
716 (i * sizeof(tSirWifiRateStat)));
717 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530718 if(!rates)
719 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530720
721 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
722 {
723 hddLog(VOS_TRACE_LEVEL_ERROR,
724 FL("QCA_WLAN_VENDOR_ATTR put fail"));
725 return FALSE;
726 }
727 nla_nest_end(vendor_event, rates);
728 }
729 nla_nest_end(vendor_event, rateInfo);
730
731 return TRUE;
732error:
733 return FALSE;
734}
735
736static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
737 struct sk_buff *vendor_event)
738{
739 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
740 stats->ac ) ||
741 nla_put_u32(vendor_event,
742 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
743 stats->txMpdu ) ||
744 nla_put_u32(vendor_event,
745 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
746 stats->rxMpdu ) ||
747 nla_put_u32(vendor_event,
748 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
749 stats->txMcast ) ||
750 nla_put_u32(vendor_event,
751 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
752 stats->rxMcast ) ||
753 nla_put_u32(vendor_event,
754 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
755 stats->rxAmpdu ) ||
756 nla_put_u32(vendor_event,
757 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
758 stats->txAmpdu ) ||
759 nla_put_u32(vendor_event,
760 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
761 stats->mpduLost )||
762 nla_put_u32(vendor_event,
763 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
764 stats->retries ) ||
765 nla_put_u32(vendor_event,
766 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
767 stats->retriesShort ) ||
768 nla_put_u32(vendor_event,
769 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
770 stats->retriesLong ) ||
771 nla_put_u32(vendor_event,
772 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
773 stats->contentionTimeMin ) ||
774 nla_put_u32(vendor_event,
775 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
776 stats->contentionTimeMax ) ||
777 nla_put_u32(vendor_event,
778 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
779 stats->contentionTimeAvg ) ||
780 nla_put_u32(vendor_event,
781 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
782 stats->contentionNumSamples ))
783 {
784 hddLog(VOS_TRACE_LEVEL_ERROR,
785 FL("QCA_WLAN_VENDOR_ATTR put fail") );
786 return FALSE;
787 }
788 return TRUE;
789}
790
791static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
792 struct sk_buff *vendor_event)
793{
Dino Myclec8f3f332014-07-21 16:48:27 +0530794 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530795 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
796 nla_put(vendor_event,
797 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
798 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
799 nla_put_u32(vendor_event,
800 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
801 stats->state ) ||
802 nla_put_u32(vendor_event,
803 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
804 stats->roaming ) ||
805 nla_put_u32(vendor_event,
806 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
807 stats->capabilities ) ||
808 nla_put(vendor_event,
809 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
810 strlen(stats->ssid), stats->ssid) ||
811 nla_put(vendor_event,
812 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
813 WNI_CFG_BSSID_LEN, stats->bssid) ||
814 nla_put(vendor_event,
815 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
816 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
817 nla_put(vendor_event,
818 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
819 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
820 )
821 {
822 hddLog(VOS_TRACE_LEVEL_ERROR,
823 FL("QCA_WLAN_VENDOR_ATTR put fail") );
824 return FALSE;
825 }
826 return TRUE;
827}
828
Dino Mycle3b9536d2014-07-09 22:05:24 +0530829static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
830 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530831 struct sk_buff *vendor_event)
832{
833 int i = 0;
834 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530835 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
836 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530837 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530838
Sunil Duttc69bccb2014-05-26 21:30:20 +0530839 if (FALSE == put_wifi_interface_info(
840 &pWifiIfaceStat->info,
841 vendor_event))
842 {
843 hddLog(VOS_TRACE_LEVEL_ERROR,
844 FL("QCA_WLAN_VENDOR_ATTR put fail") );
845 return FALSE;
846
847 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530848 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
849 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
850 if (NULL == pWifiIfaceStatTL)
851 {
852 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
853 return FALSE;
854 }
855
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530856 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
857 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
858 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
859 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
860
861 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
862 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
863 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
864 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530865
866 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
867 {
868 if (VOS_STATUS_SUCCESS ==
869 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
870 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
871 {
872 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
873 * obtained from TL structure
874 */
875
876 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
877 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530878 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
879
Srinivas Dasari98947432014-11-07 19:41:24 +0530880 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
881 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
882 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
883 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
884 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
885 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
886 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
887 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530888
Srinivas Dasari98947432014-11-07 19:41:24 +0530889 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
890 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
891 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
892 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
893 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
894 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
895 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
896 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530897
Srinivas Dasari98947432014-11-07 19:41:24 +0530898 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
899 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
900 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
901 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
902 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
903 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
904 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
905 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530906 }
907 else
908 {
909 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
910 }
911
Dino Mycle3b9536d2014-07-09 22:05:24 +0530912 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
913 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
914 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
915 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
916 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
917 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
918 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
919 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
920 }
921 else
922 {
923 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
924 }
925
926
Sunil Duttc69bccb2014-05-26 21:30:20 +0530927
928 if (nla_put_u32(vendor_event,
929 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
930 pWifiIfaceStat->beaconRx) ||
931 nla_put_u32(vendor_event,
932 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
933 pWifiIfaceStat->mgmtRx) ||
934 nla_put_u32(vendor_event,
935 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
936 pWifiIfaceStat->mgmtActionRx) ||
937 nla_put_u32(vendor_event,
938 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
939 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530940 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530941 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
942 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530943 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530944 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
945 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530946 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530947 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
948 pWifiIfaceStat->rssiAck))
949 {
950 hddLog(VOS_TRACE_LEVEL_ERROR,
951 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530952 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530953 return FALSE;
954 }
955
956 wmmInfo = nla_nest_start(vendor_event,
957 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530958 if(!wmmInfo)
959 {
960 vos_mem_free(pWifiIfaceStatTL);
961 return FALSE;
962 }
Sunil Duttc69bccb2014-05-26 21:30:20 +0530963 for (i = 0; i < WIFI_AC_MAX; i++)
964 {
965 struct nlattr *wmmStats;
966 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530967 if(!wmmStats)
968 {
969 vos_mem_free(pWifiIfaceStatTL);
970 return FALSE;
971 }
Sunil Duttc69bccb2014-05-26 21:30:20 +0530972 if (FALSE == put_wifi_wmm_ac_stat(
973 &pWifiIfaceStat->AccessclassStats[i],
974 vendor_event))
975 {
976 hddLog(VOS_TRACE_LEVEL_ERROR,
977 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530978 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530979 return FALSE;
980 }
981
982 nla_nest_end(vendor_event, wmmStats);
983 }
984 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +0530985 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530986 return TRUE;
987}
988
989static tSirWifiInterfaceMode
990 hdd_map_device_to_ll_iface_mode ( int deviceMode )
991{
992 switch (deviceMode)
993 {
994 case WLAN_HDD_INFRA_STATION:
995 return WIFI_INTERFACE_STA;
996 case WLAN_HDD_SOFTAP:
997 return WIFI_INTERFACE_SOFTAP;
998 case WLAN_HDD_P2P_CLIENT:
999 return WIFI_INTERFACE_P2P_CLIENT;
1000 case WLAN_HDD_P2P_GO:
1001 return WIFI_INTERFACE_P2P_GO;
1002 case WLAN_HDD_IBSS:
1003 return WIFI_INTERFACE_IBSS;
1004 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301005 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301006 }
1007}
1008
1009static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1010 tpSirWifiInterfaceInfo pInfo)
1011{
1012 v_U8_t *staMac = NULL;
1013 hdd_station_ctx_t *pHddStaCtx;
1014 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1015 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1016
1017 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1018
1019 vos_mem_copy(pInfo->macAddr,
1020 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1021
1022 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1023 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1024 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1025 {
1026 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1027 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1028 {
1029 pInfo->state = WIFI_DISCONNECTED;
1030 }
1031 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1032 {
1033 hddLog(VOS_TRACE_LEVEL_ERROR,
1034 "%s: Session ID %d, Connection is in progress", __func__,
1035 pAdapter->sessionId);
1036 pInfo->state = WIFI_ASSOCIATING;
1037 }
1038 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1039 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1040 {
1041 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1042 hddLog(VOS_TRACE_LEVEL_ERROR,
1043 "%s: client " MAC_ADDRESS_STR
1044 " is in the middle of WPS/EAPOL exchange.", __func__,
1045 MAC_ADDR_ARRAY(staMac));
1046 pInfo->state = WIFI_AUTHENTICATING;
1047 }
1048 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1049 {
1050 pInfo->state = WIFI_ASSOCIATED;
1051 vos_mem_copy(pInfo->bssid,
1052 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1053 vos_mem_copy(pInfo->ssid,
1054 pHddStaCtx->conn_info.SSID.SSID.ssId,
1055 pHddStaCtx->conn_info.SSID.SSID.length);
1056 //NULL Terminate the string.
1057 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1058 }
1059 }
1060 vos_mem_copy(pInfo->countryStr,
1061 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1062
1063 vos_mem_copy(pInfo->apCountryStr,
1064 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1065
1066 return TRUE;
1067}
1068
1069/*
1070 * hdd_link_layer_process_peer_stats () - This function is called after
1071 * receiving Link Layer Peer statistics from FW.This function converts
1072 * the firmware data to the NL data and sends the same to the kernel/upper
1073 * layers.
1074 */
1075static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1076 v_VOID_t *pData)
1077{
1078 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1079 tpSirWifiRateStat pWifiRateStat;
1080 tpSirWifiPeerStat pWifiPeerStat;
1081 tpSirWifiPeerInfo pWifiPeerInfo;
1082 struct nlattr *peerInfo;
1083 struct sk_buff *vendor_event;
1084 int status, i;
1085
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301086 ENTER();
1087
Sunil Duttc69bccb2014-05-26 21:30:20 +05301088 status = wlan_hdd_validate_context(pHddCtx);
1089 if (0 != status)
1090 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301091 return;
1092 }
1093
1094 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1095
1096 hddLog(VOS_TRACE_LEVEL_INFO,
1097 "LL_STATS_PEER_ALL : numPeers %u",
1098 pWifiPeerStat->numPeers);
1099 {
1100 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1101 {
1102 pWifiPeerInfo = (tpSirWifiPeerInfo)
1103 ((uint8 *)pWifiPeerStat->peerInfo +
1104 ( i * sizeof(tSirWifiPeerInfo)));
1105
Dasari Srinivas1be0c4e2014-10-19 13:03:41 +05301106 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) {
1107 pWifiPeerInfo->type = WIFI_PEER_AP;
1108 }
1109 if (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
1110 pWifiPeerInfo->type = WIFI_PEER_P2P_GO;
1111 }
1112
Sunil Duttc69bccb2014-05-26 21:30:20 +05301113 hddLog(VOS_TRACE_LEVEL_INFO,
1114 " %d) LL_STATS Channel Stats "
1115 " Peer Type %u "
1116 " peerMacAddress %pM "
1117 " capabilities 0x%x "
1118 " numRate %u ",
1119 i,
1120 pWifiPeerInfo->type,
1121 pWifiPeerInfo->peerMacAddress,
1122 pWifiPeerInfo->capabilities,
1123 pWifiPeerInfo->numRate);
1124 {
1125 int j;
1126 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1127 {
1128 pWifiRateStat = (tpSirWifiRateStat)
1129 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1130 ( j * sizeof(tSirWifiRateStat)));
1131
1132 hddLog(VOS_TRACE_LEVEL_INFO,
1133 " peer Rate Stats "
1134 " preamble %u "
1135 " nss %u "
1136 " bw %u "
1137 " rateMcsIdx %u "
1138 " reserved %u "
1139 " bitrate %u "
1140 " txMpdu %u "
1141 " rxMpdu %u "
1142 " mpduLost %u "
1143 " retries %u "
1144 " retriesShort %u "
1145 " retriesLong %u",
1146 pWifiRateStat->rate.preamble,
1147 pWifiRateStat->rate.nss,
1148 pWifiRateStat->rate.bw,
1149 pWifiRateStat->rate.rateMcsIdx,
1150 pWifiRateStat->rate.reserved,
1151 pWifiRateStat->rate.bitrate,
1152 pWifiRateStat->txMpdu,
1153 pWifiRateStat->rxMpdu,
1154 pWifiRateStat->mpduLost,
1155 pWifiRateStat->retries,
1156 pWifiRateStat->retriesShort,
1157 pWifiRateStat->retriesLong);
1158 }
1159 }
1160 }
1161 }
1162
1163 /*
1164 * Allocate a size of 4096 for the peer stats comprising
1165 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1166 * sizeof (tSirWifiRateStat).Each field is put with an
1167 * NL attribute.The size of 4096 is considered assuming
1168 * that number of rates shall not exceed beyond 50 with
1169 * the sizeof (tSirWifiRateStat) being 32.
1170 */
1171 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1172 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1173 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1174 GFP_KERNEL);
1175 if (!vendor_event)
1176 {
1177 hddLog(VOS_TRACE_LEVEL_ERROR,
1178 "%s: cfg80211_vendor_event_alloc failed",
1179 __func__);
1180 return;
1181 }
1182 if (nla_put_u32(vendor_event,
1183 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1184 pWifiPeerStat->numPeers))
1185 {
1186 hddLog(VOS_TRACE_LEVEL_ERROR,
1187 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1188 kfree_skb(vendor_event);
1189 return;
1190 }
1191
1192 peerInfo = nla_nest_start(vendor_event,
1193 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301194 if(!peerInfo)
1195 {
1196 hddLog(VOS_TRACE_LEVEL_ERROR,
1197 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1198 __func__);
1199 kfree_skb(vendor_event);
1200 return;
1201 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301202
1203 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1204 pWifiPeerStat->peerInfo);
1205
1206 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1207 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301208 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301209 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301210
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301211 if(!peers)
1212 {
1213 hddLog(VOS_TRACE_LEVEL_ERROR,
1214 "%s: peer stats put fail",
1215 __func__);
1216 kfree_skb(vendor_event);
1217 return;
1218 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301219 if (FALSE == put_wifi_peer_info(
1220 pWifiPeerInfo, vendor_event))
1221 {
1222 hddLog(VOS_TRACE_LEVEL_ERROR,
1223 "%s: put_wifi_peer_info put fail", __func__);
1224 kfree_skb(vendor_event);
1225 return;
1226 }
1227
1228 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1229 pWifiPeerStat->peerInfo +
1230 (i * sizeof(tSirWifiPeerInfo)) +
1231 (numRate * sizeof (tSirWifiRateStat)));
1232 nla_nest_end(vendor_event, peers);
1233 }
1234 nla_nest_end(vendor_event, peerInfo);
1235 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301236
1237 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301238}
1239
1240/*
1241 * hdd_link_layer_process_iface_stats () - This function is called after
1242 * receiving Link Layer Interface statistics from FW.This function converts
1243 * the firmware data to the NL data and sends the same to the kernel/upper
1244 * layers.
1245 */
1246static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1247 v_VOID_t *pData)
1248{
1249 tpSirWifiIfaceStat pWifiIfaceStat;
1250 struct sk_buff *vendor_event;
1251 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1252 int status;
1253
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301254 ENTER();
1255
Sunil Duttc69bccb2014-05-26 21:30:20 +05301256 status = wlan_hdd_validate_context(pHddCtx);
1257 if (0 != status)
1258 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301259 return;
1260 }
1261 /*
1262 * Allocate a size of 4096 for the interface stats comprising
1263 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1264 * assuming that all these fit with in the limit.Please take
1265 * a call on the limit based on the data requirements on
1266 * interface statistics.
1267 */
1268 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1269 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1270 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1271 GFP_KERNEL);
1272 if (!vendor_event)
1273 {
1274 hddLog(VOS_TRACE_LEVEL_ERROR,
1275 FL("cfg80211_vendor_event_alloc failed") );
1276 return;
1277 }
1278
1279 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1280
Dino Mycle3b9536d2014-07-09 22:05:24 +05301281
1282 if (FALSE == hdd_get_interface_info( pAdapter,
1283 &pWifiIfaceStat->info))
1284 {
1285 hddLog(VOS_TRACE_LEVEL_ERROR,
1286 FL("hdd_get_interface_info get fail") );
1287 kfree_skb(vendor_event);
1288 return;
1289 }
1290
1291 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1292 vendor_event))
1293 {
1294 hddLog(VOS_TRACE_LEVEL_ERROR,
1295 FL("put_wifi_iface_stats fail") );
1296 kfree_skb(vendor_event);
1297 return;
1298 }
1299
Sunil Duttc69bccb2014-05-26 21:30:20 +05301300 hddLog(VOS_TRACE_LEVEL_INFO,
1301 "WMI_LINK_STATS_IFACE Data");
1302
1303 hddLog(VOS_TRACE_LEVEL_INFO,
1304 "LL_STATS_IFACE: "
1305 " Mode %u "
1306 " MAC %pM "
1307 " State %u "
1308 " Roaming %u "
1309 " capabilities 0x%x "
1310 " SSID %s "
1311 " BSSID %pM",
1312 pWifiIfaceStat->info.mode,
1313 pWifiIfaceStat->info.macAddr,
1314 pWifiIfaceStat->info.state,
1315 pWifiIfaceStat->info.roaming,
1316 pWifiIfaceStat->info.capabilities,
1317 pWifiIfaceStat->info.ssid,
1318 pWifiIfaceStat->info.bssid);
1319
1320 hddLog(VOS_TRACE_LEVEL_INFO,
1321 " AP country str: %c%c%c",
1322 pWifiIfaceStat->info.apCountryStr[0],
1323 pWifiIfaceStat->info.apCountryStr[1],
1324 pWifiIfaceStat->info.apCountryStr[2]);
1325
1326
1327 hddLog(VOS_TRACE_LEVEL_INFO,
1328 " Country Str Association: %c%c%c",
1329 pWifiIfaceStat->info.countryStr[0],
1330 pWifiIfaceStat->info.countryStr[1],
1331 pWifiIfaceStat->info.countryStr[2]);
1332
1333 hddLog(VOS_TRACE_LEVEL_INFO,
1334 " beaconRx %u "
1335 " mgmtRx %u "
1336 " mgmtActionRx %u "
1337 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301338 " rssiMgmt %d "
1339 " rssiData %d "
1340 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301341 pWifiIfaceStat->beaconRx,
1342 pWifiIfaceStat->mgmtRx,
1343 pWifiIfaceStat->mgmtActionRx,
1344 pWifiIfaceStat->mgmtActionTx,
1345 pWifiIfaceStat->rssiMgmt,
1346 pWifiIfaceStat->rssiData,
1347 pWifiIfaceStat->rssiAck );
1348
1349
1350 {
1351 int i;
1352 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1353 {
1354 hddLog(VOS_TRACE_LEVEL_INFO,
1355
1356 " %d) LL_STATS IFACE: "
1357 " ac: %u txMpdu: %u "
1358 " rxMpdu: %u txMcast: %u "
1359 " rxMcast: %u rxAmpdu: %u "
1360 " txAmpdu: %u mpduLost: %u "
1361 " retries: %u retriesShort: %u "
1362 " retriesLong: %u contentionTimeMin: %u "
1363 " contentionTimeMax: %u contentionTimeAvg: %u "
1364 " contentionNumSamples: %u",
1365 i,
1366 pWifiIfaceStat->AccessclassStats[i].ac,
1367 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1368 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1369 pWifiIfaceStat->AccessclassStats[i].txMcast,
1370 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1371 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1372 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1373 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1374 pWifiIfaceStat->AccessclassStats[i].retries,
1375 pWifiIfaceStat->
1376 AccessclassStats[i].retriesShort,
1377 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1378 pWifiIfaceStat->
1379 AccessclassStats[i].contentionTimeMin,
1380 pWifiIfaceStat->
1381 AccessclassStats[i].contentionTimeMax,
1382 pWifiIfaceStat->
1383 AccessclassStats[i].contentionTimeAvg,
1384 pWifiIfaceStat->
1385 AccessclassStats[i].contentionNumSamples);
1386
1387 }
1388 }
1389
Sunil Duttc69bccb2014-05-26 21:30:20 +05301390 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301391
1392 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301393}
1394
1395/*
1396 * hdd_link_layer_process_radio_stats () - This function is called after
1397 * receiving Link Layer Radio statistics from FW.This function converts
1398 * the firmware data to the NL data and sends the same to the kernel/upper
1399 * layers.
1400 */
1401static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1402 v_VOID_t *pData)
1403{
1404 int status, i;
1405 tpSirWifiRadioStat pWifiRadioStat;
1406 tpSirWifiChannelStats pWifiChannelStats;
1407 struct sk_buff *vendor_event;
1408 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1409 struct nlattr *chList;
1410
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301411 ENTER();
1412
Sunil Duttc69bccb2014-05-26 21:30:20 +05301413 status = wlan_hdd_validate_context(pHddCtx);
1414 if (0 != status)
1415 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301416 return;
1417 }
1418 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1419
1420 hddLog(VOS_TRACE_LEVEL_INFO,
1421 "LL_STATS_RADIO"
1422 " radio is %d onTime is %u "
1423 " txTime is %u rxTime is %u "
1424 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301425 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301426 " onTimePnoScan is %u onTimeHs20 is %u "
1427 " numChannels is %u",
1428 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1429 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1430 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301431 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301432 pWifiRadioStat->onTimeRoamScan,
1433 pWifiRadioStat->onTimePnoScan,
1434 pWifiRadioStat->onTimeHs20,
1435 pWifiRadioStat->numChannels);
1436 /*
1437 * Allocate a size of 4096 for the Radio stats comprising
1438 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1439 * (tSirWifiChannelStats).Each channel data is put with an
1440 * NL attribute.The size of 4096 is considered assuming that
1441 * number of channels shall not exceed beyond 60 with the
1442 * sizeof (tSirWifiChannelStats) being 24 bytes.
1443 */
1444
1445 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1446 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1447 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1448 GFP_KERNEL);
1449
1450 if (!vendor_event)
1451 {
1452 hddLog(VOS_TRACE_LEVEL_ERROR,
1453 FL("cfg80211_vendor_event_alloc failed") );
1454 return;
1455 }
1456
1457 if (nla_put_u32(vendor_event,
1458 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1459 pWifiRadioStat->radio) ||
1460 nla_put_u32(vendor_event,
1461 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1462 pWifiRadioStat->onTime) ||
1463 nla_put_u32(vendor_event,
1464 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1465 pWifiRadioStat->txTime) ||
1466 nla_put_u32(vendor_event,
1467 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1468 pWifiRadioStat->rxTime) ||
1469 nla_put_u32(vendor_event,
1470 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1471 pWifiRadioStat->onTimeScan) ||
1472 nla_put_u32(vendor_event,
1473 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1474 pWifiRadioStat->onTimeNbd) ||
1475 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301476 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1477 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301478 nla_put_u32(vendor_event,
1479 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1480 pWifiRadioStat->onTimeRoamScan) ||
1481 nla_put_u32(vendor_event,
1482 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1483 pWifiRadioStat->onTimePnoScan) ||
1484 nla_put_u32(vendor_event,
1485 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1486 pWifiRadioStat->onTimeHs20) ||
1487 nla_put_u32(vendor_event,
1488 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1489 pWifiRadioStat->numChannels))
1490 {
1491 hddLog(VOS_TRACE_LEVEL_ERROR,
1492 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1493 kfree_skb(vendor_event);
1494 return ;
1495 }
1496
1497 chList = nla_nest_start(vendor_event,
1498 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301499 if(!chList)
1500 {
1501 hddLog(VOS_TRACE_LEVEL_ERROR,
1502 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1503 __func__);
1504 kfree_skb(vendor_event);
1505 return;
1506 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301507 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1508 {
1509 struct nlattr *chInfo;
1510
1511 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1512 pWifiRadioStat->channels +
1513 (i * sizeof(tSirWifiChannelStats)));
1514
1515 hddLog(VOS_TRACE_LEVEL_INFO,
1516 " %d) Channel Info"
1517 " width is %u "
1518 " CenterFreq %u "
1519 " CenterFreq0 %u "
1520 " CenterFreq1 %u "
1521 " onTime %u "
1522 " ccaBusyTime %u",
1523 i,
1524 pWifiChannelStats->channel.width,
1525 pWifiChannelStats->channel.centerFreq,
1526 pWifiChannelStats->channel.centerFreq0,
1527 pWifiChannelStats->channel.centerFreq1,
1528 pWifiChannelStats->onTime,
1529 pWifiChannelStats->ccaBusyTime);
1530
1531
1532 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301533 if(!chInfo)
1534 {
1535 hddLog(VOS_TRACE_LEVEL_ERROR,
1536 "%s: failed to put chInfo",
1537 __func__);
1538 kfree_skb(vendor_event);
1539 return;
1540 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301541
1542 if (nla_put_u32(vendor_event,
1543 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1544 pWifiChannelStats->channel.width) ||
1545 nla_put_u32(vendor_event,
1546 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1547 pWifiChannelStats->channel.centerFreq) ||
1548 nla_put_u32(vendor_event,
1549 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1550 pWifiChannelStats->channel.centerFreq0) ||
1551 nla_put_u32(vendor_event,
1552 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1553 pWifiChannelStats->channel.centerFreq1) ||
1554 nla_put_u32(vendor_event,
1555 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1556 pWifiChannelStats->onTime) ||
1557 nla_put_u32(vendor_event,
1558 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1559 pWifiChannelStats->ccaBusyTime))
1560 {
1561 hddLog(VOS_TRACE_LEVEL_ERROR,
1562 FL("cfg80211_vendor_event_alloc failed") );
1563 kfree_skb(vendor_event);
1564 return ;
1565 }
1566 nla_nest_end(vendor_event, chInfo);
1567 }
1568 nla_nest_end(vendor_event, chList);
1569
1570 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301571
1572 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301573 return;
1574}
1575
1576/*
1577 * hdd_link_layer_stats_ind_callback () - This function is called after
1578 * receiving Link Layer indications from FW.This callback converts the firmware
1579 * data to the NL data and send the same to the kernel/upper layers.
1580 */
1581static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1582 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301583 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301584{
Dino Mycled3d50022014-07-07 12:58:25 +05301585 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1586 hdd_adapter_t *pAdapter = NULL;
1587 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301588 int status;
1589
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301590 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301591
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301592 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301593 if (0 != status)
1594 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301595 return;
1596 }
1597
Dino Mycled3d50022014-07-07 12:58:25 +05301598 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1599 if (NULL == pAdapter)
1600 {
1601 hddLog(VOS_TRACE_LEVEL_ERROR,
1602 FL(" MAC address %pM does not exist with host"),
1603 macAddr);
1604 return;
1605 }
1606
Sunil Duttc69bccb2014-05-26 21:30:20 +05301607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301608 "%s: Interface: %s LLStats indType: %d", __func__,
1609 pAdapter->dev->name, indType);
1610
Sunil Duttc69bccb2014-05-26 21:30:20 +05301611 switch (indType)
1612 {
1613 case SIR_HAL_LL_STATS_RESULTS_RSP:
1614 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301615 hddLog(VOS_TRACE_LEVEL_INFO,
1616 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1617 hddLog(VOS_TRACE_LEVEL_INFO,
1618 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1619 linkLayerStatsResults->paramId);
1620 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301621 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1622 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301623 hddLog(VOS_TRACE_LEVEL_INFO,
1624 "LL_STATS RESULTS RESPONSE respId = %u",
1625 linkLayerStatsResults->respId);
1626 hddLog(VOS_TRACE_LEVEL_INFO,
1627 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1628 linkLayerStatsResults->moreResultToFollow);
1629 hddLog(VOS_TRACE_LEVEL_INFO,
1630 "LL_STATS RESULTS RESPONSE result = %p",
1631 linkLayerStatsResults->result);
1632 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1633 {
1634 hdd_link_layer_process_radio_stats(pAdapter,
1635 (v_VOID_t *)linkLayerStatsResults->result);
1636 }
1637 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1638 {
1639 hdd_link_layer_process_iface_stats(pAdapter,
1640 (v_VOID_t *)linkLayerStatsResults->result);
1641 }
1642 else if ( linkLayerStatsResults->paramId &
1643 WMI_LINK_STATS_ALL_PEER )
1644 {
1645 hdd_link_layer_process_peer_stats(pAdapter,
1646 (v_VOID_t *)linkLayerStatsResults->result);
1647 } /* WMI_LINK_STATS_ALL_PEER */
1648 else
1649 {
1650 hddLog(VOS_TRACE_LEVEL_ERROR,
1651 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1652 }
1653
1654 break;
1655 }
1656 default:
1657 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1658 break;
1659 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301660
1661 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301662 return;
1663}
1664
1665const struct
1666nla_policy
1667qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1668{
1669 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1670 { .type = NLA_U32 },
1671 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1672 { .type = NLA_U32 },
1673};
1674
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301675static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1676 struct wireless_dev *wdev,
1677 const void *data,
1678 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301679{
1680 int status;
1681 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301682 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301683 struct net_device *dev = wdev->netdev;
1684 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1685 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Srinivas Dasari98947432014-11-07 19:41:24 +05301686 hdd_station_ctx_t *pHddStaCtx;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301687
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301688 ENTER();
1689
Sunil Duttc69bccb2014-05-26 21:30:20 +05301690 status = wlan_hdd_validate_context(pHddCtx);
1691 if (0 != status)
1692 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301693 return -EINVAL;
1694 }
1695
1696 if (NULL == pAdapter)
1697 {
1698 hddLog(VOS_TRACE_LEVEL_ERROR,
1699 FL("HDD adapter is Null"));
1700 return -ENODEV;
1701 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301702 /* check the LLStats Capability */
1703 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1704 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1705 {
1706 hddLog(VOS_TRACE_LEVEL_ERROR,
1707 FL("Link Layer Statistics not supported by Firmware"));
1708 return -EINVAL;
1709 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301710
1711 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1712 (struct nlattr *)data,
1713 data_len, qca_wlan_vendor_ll_set_policy))
1714 {
1715 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1716 return -EINVAL;
1717 }
1718 if (!tb_vendor
1719 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1720 {
1721 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1722 return -EINVAL;
1723 }
1724 if (!tb_vendor[
1725 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1726 {
1727 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1728 return -EINVAL;
1729 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301730 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301731 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301732
Dino Mycledf0a5d92014-07-04 09:41:55 +05301733 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301734 nla_get_u32(
1735 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1736
Dino Mycledf0a5d92014-07-04 09:41:55 +05301737 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301738 nla_get_u32(
1739 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1740
Dino Mycled3d50022014-07-07 12:58:25 +05301741 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1742 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301743
1744
1745 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301746 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301747 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301748 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301749 hddLog(VOS_TRACE_LEVEL_INFO,
1750 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301751 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301752 hddLog(VOS_TRACE_LEVEL_INFO,
1753 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301754 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301755
1756 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1757 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301758 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301759 {
1760 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1761 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301762 return -EINVAL;
1763
1764 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301765
1766 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1767 if (VOS_STATUS_SUCCESS !=
1768 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1769 pHddStaCtx->conn_info.staId[0], WIFI_STATS_IFACE))
1770 {
1771 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1772 "WLANTL_ClearInterfaceStats Failed", __func__);
1773 return -EINVAL;
1774 }
1775
1776 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
1777 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
1778 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
1779 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
1780
Sunil Duttc69bccb2014-05-26 21:30:20 +05301781 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301782 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301783 {
1784 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1785 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301786 return -EINVAL;
1787 }
1788
1789 pAdapter->isLinkLayerStatsSet = 1;
1790
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301791 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301792 return 0;
1793}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301794static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1795 struct wireless_dev *wdev,
1796 const void *data,
1797 int data_len)
1798{
1799 int ret = 0;
1800
1801 vos_ssr_protect(__func__);
1802 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1803 vos_ssr_unprotect(__func__);
1804
1805 return ret;
1806}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301807
1808const struct
1809nla_policy
1810qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1811{
1812 /* Unsigned 32bit value provided by the caller issuing the GET stats
1813 * command. When reporting
1814 * the stats results, the driver uses the same value to indicate
1815 * which GET request the results
1816 * correspond to.
1817 */
1818 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1819
1820 /* Unsigned 32bit value . bit mask to identify what statistics are
1821 requested for retrieval */
1822 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1823};
1824
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301825static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1826 struct wireless_dev *wdev,
1827 const void *data,
1828 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301829{
1830 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1831 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301832 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301833 struct net_device *dev = wdev->netdev;
1834 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1835 int status;
1836
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301837 ENTER();
1838
Sunil Duttc69bccb2014-05-26 21:30:20 +05301839 status = wlan_hdd_validate_context(pHddCtx);
1840 if (0 != status)
1841 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301842 return -EINVAL ;
1843 }
1844
1845 if (NULL == pAdapter)
1846 {
1847 hddLog(VOS_TRACE_LEVEL_FATAL,
1848 "%s: HDD adapter is Null", __func__);
1849 return -ENODEV;
1850 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301851 /* check the LLStats Capability */
1852 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1853 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1854 {
1855 hddLog(VOS_TRACE_LEVEL_ERROR,
1856 FL("Link Layer Statistics not supported by Firmware"));
1857 return -EINVAL;
1858 }
1859
Sunil Duttc69bccb2014-05-26 21:30:20 +05301860
1861 if (!pAdapter->isLinkLayerStatsSet)
1862 {
1863 hddLog(VOS_TRACE_LEVEL_FATAL,
1864 "%s: isLinkLayerStatsSet : %d",
1865 __func__, pAdapter->isLinkLayerStatsSet);
1866 return -EINVAL;
1867 }
1868
1869 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1870 (struct nlattr *)data,
1871 data_len, qca_wlan_vendor_ll_get_policy))
1872 {
1873 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1874 return -EINVAL;
1875 }
1876
1877 if (!tb_vendor
1878 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1879 {
1880 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1881 return -EINVAL;
1882 }
1883
1884 if (!tb_vendor
1885 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1886 {
1887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1888 return -EINVAL;
1889 }
1890
Sunil Duttc69bccb2014-05-26 21:30:20 +05301891
Dino Mycledf0a5d92014-07-04 09:41:55 +05301892 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301893 nla_get_u32( tb_vendor[
1894 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301895 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301896 nla_get_u32( tb_vendor[
1897 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1898
Dino Mycled3d50022014-07-07 12:58:25 +05301899 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1900 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301901
1902 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301903 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301904 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301905 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301906 hddLog(VOS_TRACE_LEVEL_INFO,
1907 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301908 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301909
1910 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301911 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301912 {
1913 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1914 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301915 return -EINVAL;
1916 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301917
1918 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301919 return 0;
1920}
1921
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301922static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1923 struct wireless_dev *wdev,
1924 const void *data,
1925 int data_len)
1926{
1927 int ret = 0;
1928
1929 vos_ssr_protect(__func__);
1930 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1931 vos_ssr_unprotect(__func__);
1932
1933 return ret;
1934}
1935
Sunil Duttc69bccb2014-05-26 21:30:20 +05301936const struct
1937nla_policy
1938qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1939{
1940 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1941 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1942 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1943 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1944};
1945
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301946static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1947 struct wireless_dev *wdev,
1948 const void *data,
1949 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301950{
1951 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1952 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301953 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301954 struct net_device *dev = wdev->netdev;
1955 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1956 u32 statsClearReqMask;
1957 u8 stopReq;
1958 int status;
1959
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301960 ENTER();
1961
Sunil Duttc69bccb2014-05-26 21:30:20 +05301962 status = wlan_hdd_validate_context(pHddCtx);
1963 if (0 != status)
1964 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301965 return -EINVAL;
1966 }
1967
1968 if (NULL == pAdapter)
1969 {
1970 hddLog(VOS_TRACE_LEVEL_FATAL,
1971 "%s: HDD adapter is Null", __func__);
1972 return -ENODEV;
1973 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301974 /* check the LLStats Capability */
1975 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1976 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1977 {
1978 hddLog(VOS_TRACE_LEVEL_ERROR,
1979 FL("Enable LLStats Capability"));
1980 return -EINVAL;
1981 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301982
1983 if (!pAdapter->isLinkLayerStatsSet)
1984 {
1985 hddLog(VOS_TRACE_LEVEL_FATAL,
1986 "%s: isLinkLayerStatsSet : %d",
1987 __func__, pAdapter->isLinkLayerStatsSet);
1988 return -EINVAL;
1989 }
1990
1991 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1992 (struct nlattr *)data,
1993 data_len, qca_wlan_vendor_ll_clr_policy))
1994 {
1995 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1996 return -EINVAL;
1997 }
1998
1999 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2000
2001 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2002 {
2003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2004 return -EINVAL;
2005
2006 }
2007
Sunil Duttc69bccb2014-05-26 21:30:20 +05302008
Dino Mycledf0a5d92014-07-04 09:41:55 +05302009 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302010 nla_get_u32(
2011 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2012
Dino Mycledf0a5d92014-07-04 09:41:55 +05302013 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302014 nla_get_u8(
2015 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2016
2017 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302018 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302019
Dino Mycled3d50022014-07-07 12:58:25 +05302020 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2021 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302022
2023 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302024 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302025 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302026 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302027 hddLog(VOS_TRACE_LEVEL_INFO,
2028 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302029 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302030 hddLog(VOS_TRACE_LEVEL_INFO,
2031 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302032 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302033
2034 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302035 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302036 {
2037 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302038 hdd_station_ctx_t *pHddStaCtx;
2039
2040 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2041 if (VOS_STATUS_SUCCESS !=
2042 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2043 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2044 {
2045 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2046 "WLANTL_ClearInterfaceStats Failed", __func__);
2047 return -EINVAL;
2048 }
2049 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2050 (statsClearReqMask & WIFI_STATS_IFACE)) {
2051 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2052 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2053 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2054 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2055 }
2056
Sunil Duttc69bccb2014-05-26 21:30:20 +05302057 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2058 2 * sizeof(u32) +
2059 NLMSG_HDRLEN);
2060
2061 if (temp_skbuff != NULL)
2062 {
2063
2064 if (nla_put_u32(temp_skbuff,
2065 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2066 statsClearReqMask) ||
2067 nla_put_u32(temp_skbuff,
2068 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2069 stopReq))
2070 {
2071 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2072 kfree_skb(temp_skbuff);
2073 return -EINVAL;
2074 }
2075 /* If the ask is to stop the stats collection as part of clear
2076 * (stopReq = 1) , ensure that no further requests of get
2077 * go to the firmware by having isLinkLayerStatsSet set to 0.
2078 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302079 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302080 * case the firmware is just asked to clear the statistics.
2081 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302082 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302083 pAdapter->isLinkLayerStatsSet = 0;
2084 return cfg80211_vendor_cmd_reply(temp_skbuff);
2085 }
2086 return -ENOMEM;
2087 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302088
2089 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302090 return -EINVAL;
2091}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302092static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2093 struct wireless_dev *wdev,
2094 const void *data,
2095 int data_len)
2096{
2097 int ret = 0;
2098
2099 vos_ssr_protect(__func__);
2100 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2101 vos_ssr_unprotect(__func__);
2102
2103 return ret;
2104
2105
2106}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302107#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2108
Dino Mycle6fb96c12014-06-10 11:52:40 +05302109#ifdef WLAN_FEATURE_EXTSCAN
2110static const struct nla_policy
2111wlan_hdd_extscan_config_policy
2112 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2113{
2114 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2115 { .type = NLA_U32 },
2116 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2117 { .type = NLA_U32 },
2118 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2119 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2120 { .type = NLA_U32 },
2121 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2122 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2123
2124 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2125 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2126 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2127 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2128 { .type = NLA_U8 },
2129 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2130 { .type = NLA_U32 },
2131 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2132 { .type = NLA_U32 },
2133 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2134 { .type = NLA_U32 },
2135 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
2136 { .type = NLA_U8 },
2137 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2138 { .type = NLA_U8 },
2139 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2140 { .type = NLA_U8 },
2141
2142 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2143 { .type = NLA_U32 },
2144 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2145 { .type = NLA_UNSPEC },
2146 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2147 { .type = NLA_S32 },
2148 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2149 { .type = NLA_S32 },
2150 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2151 { .type = NLA_U32 },
2152 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2153 { .type = NLA_U32 },
2154 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2155 { .type = NLA_U32 },
2156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2157 = { .type = NLA_U32 },
2158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2159 { .type = NLA_U32 },
2160 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2161 NLA_U32 },
2162};
2163
2164static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2165{
2166 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2167 struct sk_buff *skb = NULL;
2168 tpSirEXTScanCapabilitiesEvent pData =
2169 (tpSirEXTScanCapabilitiesEvent) pMsg;
2170
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302171 ENTER();
2172
2173 if (wlan_hdd_validate_context(pHddCtx))
2174 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302175 return;
2176 }
2177
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302178 if (!pMsg)
2179 {
2180 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2181 return;
2182 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302183 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2184 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2185 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2186 GFP_KERNEL);
2187
2188 if (!skb) {
2189 hddLog(VOS_TRACE_LEVEL_ERROR,
2190 FL("cfg80211_vendor_event_alloc failed"));
2191 return;
2192 }
2193
2194 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2195 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2196 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2197 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2198 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2199 pData->maxRssiSampleSize);
2200 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2201 pData->maxScanReportingThreshold);
2202 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2203 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2204 pData->maxSignificantWifiChangeAPs);
2205 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2206 pData->maxBsidHistoryEntries);
2207
2208 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2209 pData->requestId) ||
2210 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2211 nla_put_u32(skb,
2212 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2213 pData->scanCacheSize) ||
2214 nla_put_u32(skb,
2215 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2216 pData->scanBuckets) ||
2217 nla_put_u32(skb,
2218 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2219 pData->maxApPerScan) ||
2220 nla_put_u32(skb,
2221 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2222 pData->maxRssiSampleSize) ||
2223 nla_put_u32(skb,
2224 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2225 pData->maxScanReportingThreshold) ||
2226 nla_put_u32(skb,
2227 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2228 pData->maxHotlistAPs) ||
2229 nla_put_u32(skb,
2230 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2231 pData->maxSignificantWifiChangeAPs) ||
2232 nla_put_u32(skb,
2233 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2234 pData->maxBsidHistoryEntries)) {
2235 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2236 goto nla_put_failure;
2237 }
2238
2239 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302240 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302241 return;
2242
2243nla_put_failure:
2244 kfree_skb(skb);
2245 return;
2246}
2247
2248
2249static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2250{
2251 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2252 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2253 struct sk_buff *skb = NULL;
2254 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2255
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302256 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302257
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302258 if (wlan_hdd_validate_context(pHddCtx)){
2259 return;
2260 }
2261 if (!pMsg)
2262 {
2263 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302264 return;
2265 }
2266
2267 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2268 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2269 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2270 GFP_KERNEL);
2271
2272 if (!skb) {
2273 hddLog(VOS_TRACE_LEVEL_ERROR,
2274 FL("cfg80211_vendor_event_alloc failed"));
2275 return;
2276 }
2277 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2278 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2279 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2280
2281 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2282 pData->requestId) ||
2283 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2284 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2285 goto nla_put_failure;
2286 }
2287
2288 /*
2289 * Store the Request ID for comparing with the requestID obtained
2290 * in other requests.HDD shall return a failure is the extscan_stop
2291 * request is issued with a different requestId as that of the
2292 * extscan_start request. Also, This requestId shall be used while
2293 * indicating the full scan results to the upper layers.
2294 * The requestId is stored with the assumption that the firmware
2295 * shall return the ext scan start request's requestId in ext scan
2296 * start response.
2297 */
2298 if (pData->status == 0)
2299 pMac->sme.extScanStartReqId = pData->requestId;
2300
2301
2302 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302303 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302304 return;
2305
2306nla_put_failure:
2307 kfree_skb(skb);
2308 return;
2309}
2310
2311
2312static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2313{
2314 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2315 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2316 struct sk_buff *skb = NULL;
2317
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302318 ENTER();
2319
2320 if (wlan_hdd_validate_context(pHddCtx)){
2321 return;
2322 }
2323 if (!pMsg)
2324 {
2325 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302326 return;
2327 }
2328
2329 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2330 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2331 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2332 GFP_KERNEL);
2333
2334 if (!skb) {
2335 hddLog(VOS_TRACE_LEVEL_ERROR,
2336 FL("cfg80211_vendor_event_alloc failed"));
2337 return;
2338 }
2339 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2340 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2341
2342 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2343 pData->requestId) ||
2344 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2346 goto nla_put_failure;
2347 }
2348
2349 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302350 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302351 return;
2352
2353nla_put_failure:
2354 kfree_skb(skb);
2355 return;
2356}
2357
2358
2359static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2360 void *pMsg)
2361{
2362 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2363 struct sk_buff *skb = NULL;
2364 tpSirEXTScanSetBssidHotListRspParams pData =
2365 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2366
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302367 ENTER();
2368
2369 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302370 return;
2371 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302372 if (!pMsg)
2373 {
2374 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2375 return;
2376 }
2377
Dino Mycle6fb96c12014-06-10 11:52:40 +05302378 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2379 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2380 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2381 GFP_KERNEL);
2382
2383 if (!skb) {
2384 hddLog(VOS_TRACE_LEVEL_ERROR,
2385 FL("cfg80211_vendor_event_alloc failed"));
2386 return;
2387 }
2388 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2389 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2390 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2391
2392 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2393 pData->requestId) ||
2394 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2396 goto nla_put_failure;
2397 }
2398
2399 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302400 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302401 return;
2402
2403nla_put_failure:
2404 kfree_skb(skb);
2405 return;
2406}
2407
2408static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2409 void *pMsg)
2410{
2411 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2412 struct sk_buff *skb = NULL;
2413 tpSirEXTScanResetBssidHotlistRspParams pData =
2414 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2415
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302416 ENTER();
2417
2418 if (wlan_hdd_validate_context(pHddCtx)) {
2419 return;
2420 }
2421 if (!pMsg)
2422 {
2423 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302424 return;
2425 }
2426
2427 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2428 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2429 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2430 GFP_KERNEL);
2431
2432 if (!skb) {
2433 hddLog(VOS_TRACE_LEVEL_ERROR,
2434 FL("cfg80211_vendor_event_alloc failed"));
2435 return;
2436 }
2437 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2438 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2439
2440 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2441 pData->requestId) ||
2442 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2443 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2444 goto nla_put_failure;
2445 }
2446
2447 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302448 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302449 return;
2450
2451nla_put_failure:
2452 kfree_skb(skb);
2453 return;
2454}
2455
2456
2457static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2458 void *pMsg)
2459{
2460 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2461 struct sk_buff *skb = NULL;
2462 tpSirEXTScanSetSignificantChangeRspParams pData =
2463 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2464
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302465 ENTER();
2466
2467 if (wlan_hdd_validate_context(pHddCtx)) {
2468 return;
2469 }
2470 if (!pMsg)
2471 {
2472 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302473 return;
2474 }
2475
2476 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2477 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2478 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2479 GFP_KERNEL);
2480
2481 if (!skb) {
2482 hddLog(VOS_TRACE_LEVEL_ERROR,
2483 FL("cfg80211_vendor_event_alloc failed"));
2484 return;
2485 }
2486 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2487 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2488 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2489
2490 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2491 pData->requestId) ||
2492 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2493 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2494 goto nla_put_failure;
2495 }
2496
2497 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302498 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302499 return;
2500
2501nla_put_failure:
2502 kfree_skb(skb);
2503 return;
2504}
2505
2506
2507static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2508 void *pMsg)
2509{
2510 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2511 struct sk_buff *skb = NULL;
2512 tpSirEXTScanResetSignificantChangeRspParams pData =
2513 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2514
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302515 ENTER();
2516
2517 if (wlan_hdd_validate_context(pHddCtx)) {
2518 return;
2519 }
2520 if (!pMsg)
2521 {
2522 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302523 return;
2524 }
2525
2526 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2527 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2528 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2529 GFP_KERNEL);
2530
2531 if (!skb) {
2532 hddLog(VOS_TRACE_LEVEL_ERROR,
2533 FL("cfg80211_vendor_event_alloc failed"));
2534 return;
2535 }
2536 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2537 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2538 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2539
2540 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2541 pData->requestId) ||
2542 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2543 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2544 goto nla_put_failure;
2545 }
2546
2547 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302548 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302549 return;
2550
2551nla_put_failure:
2552 kfree_skb(skb);
2553 return;
2554}
2555
2556static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2557 void *pMsg)
2558{
2559 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2560 struct sk_buff *skb = NULL;
2561 tANI_U32 i = 0, j, resultsPerEvent;
2562 tANI_S32 totalResults;
2563 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2564 tpSirWifiScanResult pSirWifiScanResult;
2565
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302566 ENTER();
2567
2568 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302569 return;
2570 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302571 if (!pMsg)
2572 {
2573 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2574 return;
2575 }
2576
Dino Mycle6fb96c12014-06-10 11:52:40 +05302577 totalResults = pData->numOfAps;
2578 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2579 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2580 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2581
2582 do{
2583 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2584 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2585 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2586
2587 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2588 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2589 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2590 GFP_KERNEL);
2591
2592 if (!skb) {
2593 hddLog(VOS_TRACE_LEVEL_ERROR,
2594 FL("cfg80211_vendor_event_alloc failed"));
2595 return;
2596 }
2597
2598 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2599
2600 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2601 pData->requestId) ||
2602 nla_put_u32(skb,
2603 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2604 resultsPerEvent)) {
2605 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2606 goto fail;
2607 }
2608 if (nla_put_u8(skb,
2609 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2610 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2611 {
2612 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2613 goto fail;
2614 }
2615
2616 if (resultsPerEvent) {
2617 struct nlattr *aps;
2618
2619 aps = nla_nest_start(skb,
2620 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2621 if (!aps)
2622 {
2623 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2624 goto fail;
2625 }
2626
2627 for (j = 0; j < resultsPerEvent; j++, i++) {
2628 struct nlattr *ap;
2629 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2630 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2631
2632 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2633 "Ssid (%s)"
2634 "Bssid: %pM "
2635 "Channel (%u)"
2636 "Rssi (%d)"
2637 "RTT (%u)"
2638 "RTT_SD (%u)",
2639 i,
2640 pSirWifiScanResult->ts,
2641 pSirWifiScanResult->ssid,
2642 pSirWifiScanResult->bssid,
2643 pSirWifiScanResult->channel,
2644 pSirWifiScanResult->rssi,
2645 pSirWifiScanResult->rtt,
2646 pSirWifiScanResult->rtt_sd);
2647
2648 ap = nla_nest_start(skb, j + 1);
2649 if (!ap)
2650 {
2651 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2652 goto fail;
2653 }
2654
2655 if (nla_put_u64(skb,
2656 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2657 pSirWifiScanResult->ts) )
2658 {
2659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2660 goto fail;
2661 }
2662 if (nla_put(skb,
2663 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2664 sizeof(pSirWifiScanResult->ssid),
2665 pSirWifiScanResult->ssid) )
2666 {
2667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2668 goto fail;
2669 }
2670 if (nla_put(skb,
2671 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2672 sizeof(pSirWifiScanResult->bssid),
2673 pSirWifiScanResult->bssid) )
2674 {
2675 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2676 goto fail;
2677 }
2678 if (nla_put_u32(skb,
2679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2680 pSirWifiScanResult->channel) )
2681 {
2682 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2683 goto fail;
2684 }
Dasari Srinivas90747d72014-10-08 12:16:15 +05302685 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302686 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2687 pSirWifiScanResult->rssi) )
2688 {
2689 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2690 goto fail;
2691 }
2692 if (nla_put_u32(skb,
2693 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2694 pSirWifiScanResult->rtt) )
2695 {
2696 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2697 goto fail;
2698 }
2699 if (nla_put_u32(skb,
2700 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2701 pSirWifiScanResult->rtt_sd))
2702 {
2703 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2704 goto fail;
2705 }
2706
2707 nla_nest_end(skb, ap);
2708 }
2709 nla_nest_end(skb, aps);
2710
2711 }
2712 cfg80211_vendor_event(skb, GFP_KERNEL);
2713 } while (totalResults > 0);
2714
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302715 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302716 return;
2717fail:
2718 kfree_skb(skb);
2719 return;
2720}
2721
2722static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2723 void *pMsg)
2724{
2725 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2726 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2727 struct sk_buff *skb = NULL;
2728 tANI_U32 i;
2729
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302730 ENTER();
2731
2732 if (wlan_hdd_validate_context(pHddCtx)) {
2733 return;
2734 }
2735 if (!pMsg)
2736 {
2737 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302738 return;
2739 }
2740
2741 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2742 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2743 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2744 GFP_KERNEL);
2745
2746 if (!skb) {
2747 hddLog(VOS_TRACE_LEVEL_ERROR,
2748 FL("cfg80211_vendor_event_alloc failed"));
2749 return;
2750 }
2751 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2752 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2753 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2754 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2755
2756 for (i = 0; i < pData->numOfAps; i++) {
2757 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2758 "Ssid (%s) "
2759 "Bssid (" MAC_ADDRESS_STR ") "
2760 "Channel (%u) "
2761 "Rssi (%d) "
2762 "RTT (%u) "
2763 "RTT_SD (%u) ",
2764 i,
2765 pData->ap[i].ts,
2766 pData->ap[i].ssid,
2767 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2768 pData->ap[i].channel,
2769 pData->ap[i].rssi,
2770 pData->ap[i].rtt,
2771 pData->ap[i].rtt_sd);
2772 }
2773
2774 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2775 pData->requestId) ||
2776 nla_put_u32(skb,
2777 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2778 pData->numOfAps)) {
2779 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2780 goto fail;
2781 }
2782 if (pData->numOfAps) {
2783 struct nlattr *aps;
2784
2785 aps = nla_nest_start(skb,
2786 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2787 if (!aps)
2788 goto fail;
2789
2790 for (i = 0; i < pData->numOfAps; i++) {
2791 struct nlattr *ap;
2792
2793 ap = nla_nest_start(skb, i + 1);
2794 if (!ap)
2795 goto fail;
2796
2797 if (nla_put_u64(skb,
2798 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2799 pData->ap[i].ts) ||
2800 nla_put(skb,
2801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2802 sizeof(pData->ap[i].ssid),
2803 pData->ap[i].ssid) ||
2804 nla_put(skb,
2805 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2806 sizeof(pData->ap[i].bssid),
2807 pData->ap[i].bssid) ||
2808 nla_put_u32(skb,
2809 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2810 pData->ap[i].channel) ||
2811 nla_put_s32(skb,
2812 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2813 pData->ap[i].rssi) ||
2814 nla_put_u32(skb,
2815 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2816 pData->ap[i].rtt) ||
2817 nla_put_u32(skb,
2818 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2819 pData->ap[i].rtt_sd))
2820 goto fail;
2821
2822 nla_nest_end(skb, ap);
2823 }
2824 nla_nest_end(skb, aps);
2825
2826 if (nla_put_u8(skb,
2827 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2828 pData->moreData))
2829 goto fail;
2830 }
2831
2832 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302833 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302834 return;
2835
2836fail:
2837 kfree_skb(skb);
2838 return;
2839
2840}
2841static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2842 void *pMsg)
2843{
2844 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2845 struct sk_buff *skb = NULL;
2846 tANI_U32 i, j;
2847 tpSirWifiSignificantChangeEvent pData =
2848 (tpSirWifiSignificantChangeEvent) pMsg;
2849
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302850 ENTER();
2851
2852 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302853 return;
2854 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302855 if (!pMsg)
2856 {
2857 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2858 return;
2859 }
2860
Dino Mycle6fb96c12014-06-10 11:52:40 +05302861 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2862 EXTSCAN_EVENT_BUF_SIZE,
2863 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2864 GFP_KERNEL);
2865
2866 if (!skb) {
2867 hddLog(VOS_TRACE_LEVEL_ERROR,
2868 FL("cfg80211_vendor_event_alloc failed"));
2869 return;
2870 }
2871 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2872 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2873 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2874 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2875 pData->numSigRssiBss);
2876 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2877
2878 for (i = 0; i < pData->numSigRssiBss; i++) {
2879 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2880 " num RSSI %u ",
2881 i, pData->sigRssiResult[i].bssid,
2882 pData->sigRssiResult[i].channel,
2883 pData->sigRssiResult[i].numRssi);
2884
2885 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2886
2887 hddLog(VOS_TRACE_LEVEL_INFO,
2888 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05302889 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302890
2891 }
2892 }
2893
2894
2895 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2896 pData->requestId) ||
2897 nla_put_u32(skb,
2898 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2899 pData->numSigRssiBss)) {
2900 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2901 goto fail;
2902 }
2903
2904 if (pData->numSigRssiBss) {
2905 struct nlattr *aps;
2906 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2907 if (!aps)
2908 goto fail;
2909 for (i = 0; i < pData->numSigRssiBss; i++) {
2910 struct nlattr *ap;
2911
2912 ap = nla_nest_start(skb, i);
2913 if (!ap)
2914 goto fail;
2915 if (nla_put(skb,
2916 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2917 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2918 nla_put_u32(skb,
2919 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2920 pData->sigRssiResult[i].channel) ||
2921 nla_put_u32(skb,
2922 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2923 pData->sigRssiResult[i].numRssi) ||
2924 nla_put(skb,
2925 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2926 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2927 pData->sigRssiResult[i].rssi))
2928 goto fail;
2929 nla_nest_end(skb, ap);
2930 }
2931 nla_nest_end(skb, aps);
2932 if (nla_put_u8(skb,
2933 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2934 pData->moreData))
2935 goto fail;
2936 }
2937 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302938 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302939 return;
2940fail:
2941 kfree_skb(skb);
2942 return;
2943}
2944
2945static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2946 void *pMsg)
2947{
2948 struct sk_buff *skb;
2949 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2950 tpSirWifiFullScanResultEvent pData =
2951 (tpSirWifiFullScanResultEvent) (pMsg);
2952
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302953 ENTER();
2954
2955 if (wlan_hdd_validate_context(pHddCtx)) {
2956 return;
2957 }
2958 if (!pMsg)
2959 {
2960 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302961 return;
2962 }
2963
2964 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2965 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2966 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2967 GFP_KERNEL);
2968
2969 if (!skb) {
2970 hddLog(VOS_TRACE_LEVEL_ERROR,
2971 FL("cfg80211_vendor_event_alloc failed"));
2972 return;
2973 }
2974
2975 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2976 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2977 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2978 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2979 "Ssid (%s)"
2980 "Bssid (" MAC_ADDRESS_STR ")"
2981 "Channel (%u)"
2982 "Rssi (%d)"
2983 "RTT (%u)"
2984 "RTT_SD (%u)"),
2985 pData->ap.ts,
2986 pData->ap.ssid,
2987 MAC_ADDR_ARRAY(pData->ap.bssid),
2988 pData->ap.channel,
2989 pData->ap.rssi,
2990 pData->ap.rtt,
2991 pData->ap.rtt_sd);
2992 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2993 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2994 pData->requestId) ||
2995 nla_put_u64(skb,
2996 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2997 pData->ap.ts) ||
2998 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2999 sizeof(pData->ap.ssid),
3000 pData->ap.ssid) ||
3001 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3002 WNI_CFG_BSSID_LEN,
3003 pData->ap.bssid) ||
3004 nla_put_u32(skb,
3005 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3006 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303007 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303008 pData->ap.rssi) ||
3009 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3010 pData->ap.rtt) ||
3011 nla_put_u32(skb,
3012 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3013 pData->ap.rtt_sd) ||
3014 nla_put_u16(skb,
3015 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3016 pData->ap.beaconPeriod) ||
3017 nla_put_u16(skb,
3018 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3019 pData->ap.capability) ||
3020 nla_put_u32(skb,
3021 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3022 pData->ieLength))
3023 {
3024 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3025 goto nla_put_failure;
3026 }
3027 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3028 pData->ieLength,
3029 pData->ie))
3030 {
3031 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3032 goto nla_put_failure;
3033 }
3034
3035 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303036 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303037 return;
3038
3039nla_put_failure:
3040 kfree_skb(skb);
3041 return;
3042}
3043
3044static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3045 void *pMsg)
3046{
3047 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3048 struct sk_buff *skb = NULL;
3049 tpSirEXTScanResultsAvailableIndParams pData =
3050 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3051
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303052 ENTER();
3053
3054 if (wlan_hdd_validate_context(pHddCtx)){
3055 return;
3056 }
3057 if (!pMsg)
3058 {
3059 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303060 return;
3061 }
3062
3063 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
3064 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3065 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3066 GFP_KERNEL);
3067
3068 if (!skb) {
3069 hddLog(VOS_TRACE_LEVEL_ERROR,
3070 FL("cfg80211_vendor_event_alloc failed"));
3071 return;
3072 }
3073
3074 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3075 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3076 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3077 pData->numResultsAvailable);
3078 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3079 pData->requestId) ||
3080 nla_put_u32(skb,
3081 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3082 pData->numResultsAvailable)) {
3083 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3084 goto nla_put_failure;
3085 }
3086
3087 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303088 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303089 return;
3090
3091nla_put_failure:
3092 kfree_skb(skb);
3093 return;
3094}
3095
3096static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3097{
3098 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3099 struct sk_buff *skb = NULL;
3100 tpSirEXTScanProgressIndParams pData =
3101 (tpSirEXTScanProgressIndParams) pMsg;
3102
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303103 ENTER();
3104
3105 if (wlan_hdd_validate_context(pHddCtx)){
3106 return;
3107 }
3108 if (!pMsg)
3109 {
3110 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303111 return;
3112 }
3113
3114 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
3115 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3116 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3117 GFP_KERNEL);
3118
3119 if (!skb) {
3120 hddLog(VOS_TRACE_LEVEL_ERROR,
3121 FL("cfg80211_vendor_event_alloc failed"));
3122 return;
3123 }
3124 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3125 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3126 pData->extScanEventType);
3127 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3128 pData->status);
3129
3130 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3131 pData->extScanEventType) ||
3132 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303133 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3134 pData->requestId) ||
3135 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303136 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3137 pData->status)) {
3138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3139 goto nla_put_failure;
3140 }
3141
3142 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303143 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303144 return;
3145
3146nla_put_failure:
3147 kfree_skb(skb);
3148 return;
3149}
3150
3151void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3152 void *pMsg)
3153{
3154 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3155
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303156 ENTER();
3157
Dino Mycle6fb96c12014-06-10 11:52:40 +05303158 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303159 return;
3160 }
3161
3162 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3163
3164
3165 switch(evType) {
3166 case SIR_HAL_EXTSCAN_START_RSP:
3167 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3168 break;
3169
3170 case SIR_HAL_EXTSCAN_STOP_RSP:
3171 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3172 break;
3173 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3174 /* There is no need to send this response to upper layer
3175 Just log the message */
3176 hddLog(VOS_TRACE_LEVEL_INFO,
3177 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3178 break;
3179 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3180 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3181 break;
3182
3183 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3184 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3185 break;
3186
3187 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
3188 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
3189 break;
3190
3191 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
3192 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
3193 break;
3194 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
3195 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
3196 break;
3197 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3198 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3199 break;
3200 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3201 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3202 break;
3203 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3204 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3205 break;
3206 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3207 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3208 break;
3209 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
3210 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
3211 break;
3212 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3213 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3214 break;
3215 default:
3216 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3217 break;
3218 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303219 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303220}
3221
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303222static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3223 struct wireless_dev *wdev,
3224 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303225{
Dino Myclee8843b32014-07-04 14:21:45 +05303226 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303227 struct net_device *dev = wdev->netdev;
3228 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3229 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3230 struct nlattr
3231 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3232 eHalStatus status;
3233
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303234 ENTER();
3235
Dino Mycle6fb96c12014-06-10 11:52:40 +05303236 status = wlan_hdd_validate_context(pHddCtx);
3237 if (0 != status)
3238 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303239 return -EINVAL;
3240 }
Dino Myclee8843b32014-07-04 14:21:45 +05303241 /* check the EXTScan Capability */
3242 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3243 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3244 {
3245 hddLog(VOS_TRACE_LEVEL_ERROR,
3246 FL("EXTScan not enabled/supported by Firmware"));
3247 return -EINVAL;
3248 }
3249
Dino Mycle6fb96c12014-06-10 11:52:40 +05303250 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3251 data, dataLen,
3252 wlan_hdd_extscan_config_policy)) {
3253 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3254 return -EINVAL;
3255 }
3256
3257 /* Parse and fetch request Id */
3258 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3259 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3260 return -EINVAL;
3261 }
3262
Dino Mycle6fb96c12014-06-10 11:52:40 +05303263
Dino Myclee8843b32014-07-04 14:21:45 +05303264 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303265 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303266 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303267
Dino Myclee8843b32014-07-04 14:21:45 +05303268 reqMsg.sessionId = pAdapter->sessionId;
3269 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303270
Dino Myclee8843b32014-07-04 14:21:45 +05303271 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303272 if (!HAL_STATUS_SUCCESS(status)) {
3273 hddLog(VOS_TRACE_LEVEL_ERROR,
3274 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303275 return -EINVAL;
3276 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303277 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303278 return 0;
3279}
3280
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303281static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3282 struct wireless_dev *wdev,
3283 const void *data, int dataLen)
3284{
3285 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303286
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303287 vos_ssr_protect(__func__);
3288 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3289 vos_ssr_unprotect(__func__);
3290
3291 return ret;
3292}
3293
3294static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3295 struct wireless_dev *wdev,
3296 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303297{
Dino Myclee8843b32014-07-04 14:21:45 +05303298 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303299 struct net_device *dev = wdev->netdev;
3300 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3301 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3302 struct nlattr
3303 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3304 eHalStatus status;
3305
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303306 ENTER();
3307
Dino Mycle6fb96c12014-06-10 11:52:40 +05303308 status = wlan_hdd_validate_context(pHddCtx);
3309 if (0 != status)
3310 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303311 return -EINVAL;
3312 }
Dino Myclee8843b32014-07-04 14:21:45 +05303313 /* check the EXTScan Capability */
3314 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3315 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3316 {
3317 hddLog(VOS_TRACE_LEVEL_ERROR,
3318 FL("EXTScan not enabled/supported by Firmware"));
3319 return -EINVAL;
3320 }
3321
Dino Mycle6fb96c12014-06-10 11:52:40 +05303322 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3323 data, dataLen,
3324 wlan_hdd_extscan_config_policy)) {
3325 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3326 return -EINVAL;
3327 }
3328 /* Parse and fetch request Id */
3329 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3330 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3331 return -EINVAL;
3332 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303333
Dino Myclee8843b32014-07-04 14:21:45 +05303334 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303335 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3336
Dino Myclee8843b32014-07-04 14:21:45 +05303337 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303338
Dino Myclee8843b32014-07-04 14:21:45 +05303339 reqMsg.sessionId = pAdapter->sessionId;
3340 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303341
3342 /* Parse and fetch flush parameter */
3343 if (!tb
3344 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3345 {
3346 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3347 goto failed;
3348 }
Dino Myclee8843b32014-07-04 14:21:45 +05303349 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303350 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3351
Dino Myclee8843b32014-07-04 14:21:45 +05303352 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303353
Dino Myclee8843b32014-07-04 14:21:45 +05303354 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303355 if (!HAL_STATUS_SUCCESS(status)) {
3356 hddLog(VOS_TRACE_LEVEL_ERROR,
3357 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303358 return -EINVAL;
3359 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303360 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303361 return 0;
3362
3363failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303364 return -EINVAL;
3365}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303366static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3367 struct wireless_dev *wdev,
3368 const void *data, int dataLen)
3369{
3370 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303371
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303372 vos_ssr_protect(__func__);
3373 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3374 vos_ssr_unprotect(__func__);
3375
3376 return ret;
3377}
3378
3379static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303380 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303381 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303382{
3383 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3384 struct net_device *dev = wdev->netdev;
3385 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3386 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3387 struct nlattr
3388 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3389 struct nlattr
3390 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3391 struct nlattr *apTh;
3392 eHalStatus status;
3393 tANI_U8 i = 0;
3394 int rem;
3395
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303396 ENTER();
3397
Dino Mycle6fb96c12014-06-10 11:52:40 +05303398 status = wlan_hdd_validate_context(pHddCtx);
3399 if (0 != status)
3400 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303401 return -EINVAL;
3402 }
Dino Myclee8843b32014-07-04 14:21:45 +05303403 /* check the EXTScan Capability */
3404 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3405 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3406 {
3407 hddLog(VOS_TRACE_LEVEL_ERROR,
3408 FL("EXTScan not enabled/supported by Firmware"));
3409 return -EINVAL;
3410 }
3411
Dino Mycle6fb96c12014-06-10 11:52:40 +05303412 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3413 data, dataLen,
3414 wlan_hdd_extscan_config_policy)) {
3415 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3416 return -EINVAL;
3417 }
3418
3419 /* Parse and fetch request Id */
3420 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3421 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3422 return -EINVAL;
3423 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303424 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3425 vos_mem_malloc(sizeof(*pReqMsg));
3426 if (!pReqMsg) {
3427 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3428 return -ENOMEM;
3429 }
3430
Dino Myclee8843b32014-07-04 14:21:45 +05303431
Dino Mycle6fb96c12014-06-10 11:52:40 +05303432 pReqMsg->requestId = nla_get_u32(
3433 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3434 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3435
3436 /* Parse and fetch number of APs */
3437 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3438 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3439 goto fail;
3440 }
3441
3442 pReqMsg->sessionId = pAdapter->sessionId;
3443 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3444
3445 pReqMsg->numAp = nla_get_u32(
3446 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3447 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3448
3449 nla_for_each_nested(apTh,
3450 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3451 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3452 nla_data(apTh), nla_len(apTh),
3453 NULL)) {
3454 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3455 goto fail;
3456 }
3457
3458 /* Parse and fetch MAC address */
3459 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3460 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3461 goto fail;
3462 }
3463 memcpy(pReqMsg->ap[i].bssid, nla_data(
3464 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3465 sizeof(tSirMacAddr));
3466 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3467
3468 /* Parse and fetch low RSSI */
3469 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3470 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3471 goto fail;
3472 }
3473 pReqMsg->ap[i].low = nla_get_s32(
3474 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3475 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3476
3477 /* Parse and fetch high RSSI */
3478 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3479 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3480 goto fail;
3481 }
3482 pReqMsg->ap[i].high = nla_get_s32(
3483 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3484 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3485 pReqMsg->ap[i].high);
3486
3487 /* Parse and fetch channel */
3488 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3489 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3490 goto fail;
3491 }
3492 pReqMsg->ap[i].channel = nla_get_u32(
3493 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3494 hddLog(VOS_TRACE_LEVEL_INFO,
3495 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3496 i++;
3497 }
3498 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3499 if (!HAL_STATUS_SUCCESS(status)) {
3500 hddLog(VOS_TRACE_LEVEL_ERROR,
3501 FL("sme_SetBssHotlist failed(err=%d)"), status);
3502 vos_mem_free(pReqMsg);
3503 return -EINVAL;
3504 }
3505
Dino Myclee8843b32014-07-04 14:21:45 +05303506 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303507 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303508 return 0;
3509
3510fail:
3511 vos_mem_free(pReqMsg);
3512 return -EINVAL;
3513}
3514
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303515static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3516 struct wireless_dev *wdev,
3517 const void *data, int dataLen)
3518{
3519 int ret = 0;
3520
3521 vos_ssr_protect(__func__);
3522 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3523 dataLen);
3524 vos_ssr_unprotect(__func__);
3525
3526 return ret;
3527}
3528
3529static int __wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303530 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303531 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303532{
3533 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3534 struct net_device *dev = wdev->netdev;
3535 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3536 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3537 struct nlattr
3538 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3539 struct nlattr
3540 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3541 struct nlattr *apTh;
3542 eHalStatus status;
3543 int i = 0;
3544 int rem;
3545
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303546 ENTER();
3547
Dino Mycle6fb96c12014-06-10 11:52:40 +05303548 status = wlan_hdd_validate_context(pHddCtx);
3549 if (0 != status)
3550 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303551 return -EINVAL;
3552 }
Dino Myclee8843b32014-07-04 14:21:45 +05303553 /* check the EXTScan Capability */
3554 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3555 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3556 {
3557 hddLog(VOS_TRACE_LEVEL_ERROR,
3558 FL("EXTScan not enabled/supported by Firmware"));
3559 return -EINVAL;
3560 }
3561
Dino Mycle6fb96c12014-06-10 11:52:40 +05303562 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3563 data, dataLen,
3564 wlan_hdd_extscan_config_policy)) {
3565 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3566 return -EINVAL;
3567 }
3568
3569 /* Parse and fetch request Id */
3570 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3571 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3572 return -EINVAL;
3573 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303574 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303575 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303576 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303577 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3578 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303579 }
3580
Dino Myclee8843b32014-07-04 14:21:45 +05303581
3582
Dino Mycle6fb96c12014-06-10 11:52:40 +05303583 pReqMsg->requestId = nla_get_u32(
3584 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3585 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3586
3587 /* Parse and fetch RSSI sample size */
3588 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3589 {
3590 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3591 goto fail;
3592 }
3593 pReqMsg->rssiSampleSize = nla_get_u32(
3594 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3595 hddLog(VOS_TRACE_LEVEL_INFO,
3596 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3597
3598 /* Parse and fetch lost AP sample size */
3599 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3600 {
3601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3602 goto fail;
3603 }
3604 pReqMsg->lostApSampleSize = nla_get_u32(
3605 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3606 hddLog(VOS_TRACE_LEVEL_INFO,
3607 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3608 /* Parse and fetch minimum Breaching */
3609 if (!tb
3610 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3611 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3612 goto fail;
3613 }
3614 pReqMsg->minBreaching = nla_get_u32(
3615 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3616 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3617
3618 /* Parse and fetch number of APs */
3619 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3620 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3621 goto fail;
3622 }
3623 pReqMsg->numAp = nla_get_u32(
3624 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3625 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3626
3627 pReqMsg->sessionId = pAdapter->sessionId;
3628 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3629
3630 nla_for_each_nested(apTh,
3631 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3632 if(nla_parse(tb2,
3633 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3634 nla_data(apTh), nla_len(apTh),
3635 NULL)) {
3636 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3637 goto fail;
3638 }
3639
3640 /* Parse and fetch MAC address */
3641 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3642 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3643 goto fail;
3644 }
3645 memcpy(pReqMsg->ap[i].bssid, nla_data(
3646 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3647 sizeof(tSirMacAddr));
3648
3649 /* Parse and fetch low RSSI */
3650 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3651 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3652 goto fail;
3653 }
3654 pReqMsg->ap[i].low = nla_get_s32(
3655 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3656 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3657
3658 /* Parse and fetch high RSSI */
3659 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3660 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3661 goto fail;
3662 }
3663 pReqMsg->ap[i].high = nla_get_s32(
3664 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3665 hddLog(VOS_TRACE_LEVEL_INFO,
3666 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3667
3668 /* Parse and fetch channel */
3669 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3670 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3671 goto fail;
3672 }
3673 pReqMsg->ap[i].channel = nla_get_u32(
3674 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3675 hddLog(VOS_TRACE_LEVEL_INFO,
3676 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3677 i++;
3678 }
3679
3680 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3681 if (!HAL_STATUS_SUCCESS(status)) {
3682 hddLog(VOS_TRACE_LEVEL_ERROR,
3683 FL("sme_SetSignificantChange failed(err=%d)"), status);
3684 vos_mem_free(pReqMsg);
3685 return -EINVAL;
3686 }
Dino Myclee8843b32014-07-04 14:21:45 +05303687 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303688 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303689 return 0;
3690
3691fail:
3692 vos_mem_free(pReqMsg);
3693 return -EINVAL;
3694}
3695
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303696static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3697 struct wireless_dev *wdev,
3698 const void *data, int dataLen)
3699{
3700 int ret = 0;
3701
3702 vos_ssr_protect(__func__);
3703 ret = __wlan_hdd_cfg80211_extscan_set_significant_change(wiphy, wdev, data,
3704 dataLen);
3705 vos_ssr_unprotect(__func__);
3706
3707 return ret;
3708}
3709
3710static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303711 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303712 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303713{
3714 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3715 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3716 tANI_U8 numChannels = 0;
3717 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3718 tANI_U32 requestId;
3719 tWifiBand wifiBand;
3720 eHalStatus status;
3721 struct sk_buff *replySkb;
3722 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303723 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303724
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303725 ENTER();
3726
Dino Mycle6fb96c12014-06-10 11:52:40 +05303727 status = wlan_hdd_validate_context(pHddCtx);
3728 if (0 != status)
3729 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303730 return -EINVAL;
3731 }
Dino Myclee8843b32014-07-04 14:21:45 +05303732 /* check the EXTScan Capability */
3733 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3734 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3735 {
3736 hddLog(VOS_TRACE_LEVEL_ERROR,
3737 FL("EXTScan not enabled/supported by Firmware"));
3738 return -EINVAL;
3739 }
3740
Dino Mycle6fb96c12014-06-10 11:52:40 +05303741 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3742 data, dataLen,
3743 wlan_hdd_extscan_config_policy)) {
3744 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3745 return -EINVAL;
3746 }
3747
3748 /* Parse and fetch request Id */
3749 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3750 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3751 return -EINVAL;
3752 }
3753 requestId = nla_get_u32(
3754 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3755 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3756
3757 /* Parse and fetch wifi band */
3758 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3759 {
3760 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3761 return -EINVAL;
3762 }
3763 wifiBand = nla_get_u32(
3764 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3765 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3766
3767 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3768 wifiBand, ChannelList,
3769 &numChannels);
3770 if (eHAL_STATUS_SUCCESS != status) {
3771 hddLog(VOS_TRACE_LEVEL_ERROR,
3772 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3773 return -EINVAL;
3774 }
3775 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3776 for (i = 0; i < numChannels; i++)
3777 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3778
3779 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3780 sizeof(u32) * numChannels +
3781 NLMSG_HDRLEN);
3782
3783 if (!replySkb) {
3784 hddLog(VOS_TRACE_LEVEL_ERROR,
3785 FL("valid channels: buffer alloc fail"));
3786 return -EINVAL;
3787 }
3788 if (nla_put_u32(replySkb,
3789 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3790 numChannels) ||
3791 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3792 sizeof(u32) * numChannels, ChannelList)) {
3793
3794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3795 kfree_skb(replySkb);
3796 return -EINVAL;
3797 }
3798
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303799 ret = cfg80211_vendor_cmd_reply(replySkb);
3800
3801 EXIT();
3802 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303803}
3804
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303805static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3806 struct wireless_dev *wdev,
3807 const void *data, int dataLen)
3808{
3809 int ret = 0;
3810
3811 vos_ssr_protect(__func__);
3812 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
3813 dataLen);
3814 vos_ssr_unprotect(__func__);
3815
3816 return ret;
3817}
3818
3819static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303820 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303821 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303822{
Dino Myclee8843b32014-07-04 14:21:45 +05303823 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303824 struct net_device *dev = wdev->netdev;
3825 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3826 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3827 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3828 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3829 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3830 struct nlattr *buckets;
3831 struct nlattr *channels;
3832 int rem1;
3833 int rem2;
3834 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303835 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303836
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303837 ENTER();
3838
Dino Mycle6fb96c12014-06-10 11:52:40 +05303839 status = wlan_hdd_validate_context(pHddCtx);
3840 if (0 != status)
3841 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303842 return -EINVAL;
3843 }
Dino Myclee8843b32014-07-04 14:21:45 +05303844 /* check the EXTScan Capability */
3845 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3846 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3847 {
3848 hddLog(VOS_TRACE_LEVEL_ERROR,
3849 FL("EXTScan not enabled/supported by Firmware"));
3850 return -EINVAL;
3851 }
3852
Dino Mycle6fb96c12014-06-10 11:52:40 +05303853 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3854 data, dataLen,
3855 wlan_hdd_extscan_config_policy)) {
3856 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3857 return -EINVAL;
3858 }
3859
3860 /* Parse and fetch request Id */
3861 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3862 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3863 return -EINVAL;
3864 }
3865
Dino Myclee8843b32014-07-04 14:21:45 +05303866 pReqMsg = (tpSirEXTScanStartReqParams)
3867 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303868 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303869 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3870 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303871 }
3872
3873 pReqMsg->requestId = nla_get_u32(
3874 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3875 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3876
3877 pReqMsg->sessionId = pAdapter->sessionId;
3878 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3879
3880 /* Parse and fetch base period */
3881 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3882 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3883 goto fail;
3884 }
3885 pReqMsg->basePeriod = nla_get_u32(
3886 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3887 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3888 pReqMsg->basePeriod);
3889
3890 /* Parse and fetch max AP per scan */
3891 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3892 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3893 goto fail;
3894 }
3895 pReqMsg->maxAPperScan = nla_get_u32(
3896 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3897 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3898 pReqMsg->maxAPperScan);
3899
3900 /* Parse and fetch report threshold */
3901 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3902 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3903 goto fail;
3904 }
3905 pReqMsg->reportThreshold = nla_get_u8(
3906 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3907 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3908 pReqMsg->reportThreshold);
3909
3910 /* Parse and fetch number of buckets */
3911 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3912 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3913 goto fail;
3914 }
3915 pReqMsg->numBuckets = nla_get_u8(
3916 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3917 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3918 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3919 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3920 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3921 }
3922 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3923 pReqMsg->numBuckets);
3924 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3925 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3926 goto fail;
3927 }
3928
3929 nla_for_each_nested(buckets,
3930 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3931 if(nla_parse(bucket,
3932 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3933 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3934 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3935 goto fail;
3936 }
3937
3938 /* Parse and fetch bucket spec */
3939 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3940 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3941 goto fail;
3942 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303943
3944 pReqMsg->buckets[index].bucket = nla_get_u8(
3945 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3946
3947 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
3948 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303949
3950 /* Parse and fetch wifi band */
3951 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3952 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3953 goto fail;
3954 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303955 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303956 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3957 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303958 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303959
3960 /* Parse and fetch period */
3961 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3962 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3963 goto fail;
3964 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303965 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303966 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3967 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303968 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303969
3970 /* Parse and fetch report events */
3971 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3972 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3973 goto fail;
3974 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303975 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303976 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3977 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303978 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303979
3980 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303981 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
3982 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303983 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3984 goto fail;
3985 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303986 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303987 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3988 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303989 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303990
3991 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3992 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3993 goto fail;
3994 }
3995
3996 j = 0;
3997 nla_for_each_nested(channels,
3998 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3999 if(nla_parse(channel,
4000 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4001 nla_data(channels), nla_len(channels),
4002 NULL)) { //wlan_hdd_extscan_config_policy here
4003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4004 goto fail;
4005 }
4006
4007 /* Parse and fetch channel */
4008 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4009 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4010 goto fail;
4011 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304012 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304013 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4014 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304015 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304016
4017 /* Parse and fetch dwell time */
4018 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4019 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
4020 goto fail;
4021 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304022 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304023 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4024 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304025 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304026
4027 /* Parse and fetch channel spec passive */
4028 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4029 hddLog(VOS_TRACE_LEVEL_ERROR,
4030 FL("attr channel spec passive failed"));
4031 goto fail;
4032 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304033 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304034 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4035 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304036 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304037 j++;
4038 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304039 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304040 }
4041 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4042 if (!HAL_STATUS_SUCCESS(status)) {
4043 hddLog(VOS_TRACE_LEVEL_ERROR,
4044 FL("sme_EXTScanStart failed(err=%d)"), status);
4045 vos_mem_free(pReqMsg);
4046 return -EINVAL;
4047 }
4048
Dino Myclee8843b32014-07-04 14:21:45 +05304049 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304050 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304051 return 0;
4052
4053fail:
4054 vos_mem_free(pReqMsg);
4055 return -EINVAL;
4056}
4057
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304058static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4059 struct wireless_dev *wdev,
4060 const void *data, int dataLen)
4061{
4062 int ret = 0;
4063
4064 vos_ssr_protect(__func__);
4065 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4066 vos_ssr_unprotect(__func__);
4067
4068 return ret;
4069}
4070
4071static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304072 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304073 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304074{
Dino Myclee8843b32014-07-04 14:21:45 +05304075 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304076 struct net_device *dev = wdev->netdev;
4077 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4078 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4079 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4080 eHalStatus status;
4081
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304082 ENTER();
4083
Dino Mycle6fb96c12014-06-10 11:52:40 +05304084 status = wlan_hdd_validate_context(pHddCtx);
4085 if (0 != status)
4086 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304087 return -EINVAL;
4088 }
Dino Myclee8843b32014-07-04 14:21:45 +05304089 /* check the EXTScan Capability */
4090 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4091 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4092 {
4093 hddLog(VOS_TRACE_LEVEL_ERROR,
4094 FL("EXTScan not enabled/supported by Firmware"));
4095 return -EINVAL;
4096 }
4097
Dino Mycle6fb96c12014-06-10 11:52:40 +05304098 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4099 data, dataLen,
4100 wlan_hdd_extscan_config_policy)) {
4101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4102 return -EINVAL;
4103 }
4104
4105 /* Parse and fetch request Id */
4106 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4107 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4108 return -EINVAL;
4109 }
4110
Dino Myclee8843b32014-07-04 14:21:45 +05304111 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304112 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304113 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304114
Dino Myclee8843b32014-07-04 14:21:45 +05304115 reqMsg.sessionId = pAdapter->sessionId;
4116 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304117
Dino Myclee8843b32014-07-04 14:21:45 +05304118 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304119 if (!HAL_STATUS_SUCCESS(status)) {
4120 hddLog(VOS_TRACE_LEVEL_ERROR,
4121 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304122 return -EINVAL;
4123 }
4124
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304125 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304126 return 0;
4127}
4128
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304129static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4130 struct wireless_dev *wdev,
4131 const void *data, int dataLen)
4132{
4133 int ret = 0;
4134
4135 vos_ssr_protect(__func__);
4136 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4137 vos_ssr_unprotect(__func__);
4138
4139 return ret;
4140}
4141
4142static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304143 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304144 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304145{
Dino Myclee8843b32014-07-04 14:21:45 +05304146 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304147 struct net_device *dev = wdev->netdev;
4148 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4149 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4150 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4151 eHalStatus status;
4152
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304153 ENTER();
4154
Dino Mycle6fb96c12014-06-10 11:52:40 +05304155 status = wlan_hdd_validate_context(pHddCtx);
4156 if (0 != status)
4157 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304158 return -EINVAL;
4159 }
Dino Myclee8843b32014-07-04 14:21:45 +05304160 /* check the EXTScan Capability */
4161 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4162 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4163 {
4164 hddLog(VOS_TRACE_LEVEL_ERROR,
4165 FL("EXTScan not enabled/supported by Firmware"));
4166 return -EINVAL;
4167 }
4168
Dino Mycle6fb96c12014-06-10 11:52:40 +05304169 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4170 data, dataLen,
4171 wlan_hdd_extscan_config_policy)) {
4172 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4173 return -EINVAL;
4174 }
4175
4176 /* Parse and fetch request Id */
4177 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4179 return -EINVAL;
4180 }
4181
Dino Myclee8843b32014-07-04 14:21:45 +05304182 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304183 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304184 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304185
Dino Myclee8843b32014-07-04 14:21:45 +05304186 reqMsg.sessionId = pAdapter->sessionId;
4187 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304188
Dino Myclee8843b32014-07-04 14:21:45 +05304189 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304190 if (!HAL_STATUS_SUCCESS(status)) {
4191 hddLog(VOS_TRACE_LEVEL_ERROR,
4192 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304193 return -EINVAL;
4194 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304195 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304196 return 0;
4197}
4198
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304199static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4200 struct wireless_dev *wdev,
4201 const void *data, int dataLen)
4202{
4203 int ret = 0;
4204
4205 vos_ssr_protect(__func__);
4206 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4207 vos_ssr_unprotect(__func__);
4208
4209 return ret;
4210}
4211
4212static int __wlan_hdd_cfg80211_extscan_reset_significant_change(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304213 struct wiphy *wiphy,
4214 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304215 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304216{
Dino Myclee8843b32014-07-04 14:21:45 +05304217 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304218 struct net_device *dev = wdev->netdev;
4219 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4220 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4221 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4222 eHalStatus status;
4223
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304224 ENTER();
4225
Dino Mycle6fb96c12014-06-10 11:52:40 +05304226 status = wlan_hdd_validate_context(pHddCtx);
4227 if (0 != status)
4228 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304229 return -EINVAL;
4230 }
Dino Myclee8843b32014-07-04 14:21:45 +05304231 /* check the EXTScan Capability */
4232 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4233 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4234 {
4235 hddLog(VOS_TRACE_LEVEL_ERROR,
4236 FL("EXTScan not enabled/supported by Firmware"));
4237 return -EINVAL;
4238 }
4239
Dino Mycle6fb96c12014-06-10 11:52:40 +05304240 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4241 data, dataLen,
4242 wlan_hdd_extscan_config_policy)) {
4243 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4244 return -EINVAL;
4245 }
4246
4247 /* Parse and fetch request Id */
4248 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4249 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4250 return -EINVAL;
4251 }
4252
Dino Mycle6fb96c12014-06-10 11:52:40 +05304253
Dino Myclee8843b32014-07-04 14:21:45 +05304254 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304255 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304256 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304257
Dino Myclee8843b32014-07-04 14:21:45 +05304258 reqMsg.sessionId = pAdapter->sessionId;
4259 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304260
Dino Myclee8843b32014-07-04 14:21:45 +05304261 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304262 if (!HAL_STATUS_SUCCESS(status)) {
4263 hddLog(VOS_TRACE_LEVEL_ERROR,
4264 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304265 return -EINVAL;
4266 }
4267
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304268 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304269 return 0;
4270}
4271
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304272static int wlan_hdd_cfg80211_extscan_reset_significant_change(
4273 struct wiphy *wiphy,
4274 struct wireless_dev *wdev,
4275 const void *data, int dataLen)
4276{
4277 int ret = 0;
4278
4279 vos_ssr_protect(__func__);
4280 ret = __wlan_hdd_cfg80211_extscan_reset_significant_change(wiphy,
4281 wdev, data,
4282 dataLen);
4283 vos_ssr_unprotect(__func__);
4284
4285 return ret;
4286}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304287#endif /* WLAN_FEATURE_EXTSCAN */
4288
Atul Mittal115287b2014-07-08 13:26:33 +05304289/*EXT TDLS*/
4290static const struct nla_policy
4291wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4292{
4293 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4294 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4295 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4296 {.type = NLA_S32 },
4297 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4298 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4299
4300};
4301
4302static const struct nla_policy
4303wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4304{
4305 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4306
4307};
4308
4309static const struct nla_policy
4310wlan_hdd_tdls_config_state_change_policy[
4311 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4312{
4313 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4314 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4315 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304316 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4317 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4318 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304319
4320};
4321
4322static const struct nla_policy
4323wlan_hdd_tdls_config_get_status_policy[
4324 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4325{
4326 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4327 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4328 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304329 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4330 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4331 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304332
4333};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304334
4335static const struct nla_policy
4336wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4337{
4338 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4339};
4340
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304341static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304342 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304343 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304344 int data_len)
4345{
4346
4347 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4348 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4349
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304350 ENTER();
4351
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304352 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304353 return -EINVAL;
4354 }
4355 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
4356 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN disabled in ini"));
4357 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304358 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304359 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
4360 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN not supported by FW"));
4361 return -ENOTSUPP;
4362 }
4363
4364 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4365 data, data_len, wlan_hdd_mac_config)) {
4366 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4367 return -EINVAL;
4368 }
4369
4370 /* Parse and fetch mac address */
4371 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4372 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4373 return -EINVAL;
4374 }
4375
4376 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4377 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4378 VOS_MAC_ADDR_LAST_3_BYTES);
4379
Siddharth Bhal76972212014-10-15 16:22:51 +05304380 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4381
4382 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304383 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4384 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304385 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4386 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4387 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4388 {
4389 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4390 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4391 VOS_MAC_ADDRESS_LEN);
4392 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304393 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304394
Siddharth Bhal76972212014-10-15 16:22:51 +05304395 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
4396 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304397 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4398 }
4399
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304400 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304401 return 0;
4402}
4403
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304404static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4405 struct wireless_dev *wdev,
4406 const void *data,
4407 int data_len)
4408{
4409 int ret = 0;
4410
4411 vos_ssr_protect(__func__);
4412 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
4413 vos_ssr_unprotect(__func__);
4414
4415 return ret;
4416}
4417
4418static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304419 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304420 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304421 int data_len)
4422{
4423 u8 peer[6] = {0};
4424 struct net_device *dev = wdev->netdev;
4425 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4426 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4427 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4428 eHalStatus ret;
4429 tANI_S32 state;
4430 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304431 tANI_S32 global_operating_class = 0;
4432 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304433 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304434 int retVal;
4435
4436 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304437
4438 ret = wlan_hdd_validate_context(pHddCtx);
4439 if (0 != ret) {
Atul Mittal115287b2014-07-08 13:26:33 +05304440 return -EINVAL;
4441 }
4442 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4443
4444 return -ENOTSUPP;
4445 }
4446 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4447 data, data_len,
4448 wlan_hdd_tdls_config_get_status_policy)) {
4449 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4450 return -EINVAL;
4451 }
4452
4453 /* Parse and fetch mac address */
4454 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4455 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4456 return -EINVAL;
4457 }
4458
4459 memcpy(peer, nla_data(
4460 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4461 sizeof(peer));
4462 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4463
4464 ret = wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
4465
4466 if (0 != ret) {
4467 hddLog(VOS_TRACE_LEVEL_ERROR,
4468 FL("get status Failed"));
4469 return -EINVAL;
4470 }
4471 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304472 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304473 NLMSG_HDRLEN);
4474
4475 if (!skb) {
4476 hddLog(VOS_TRACE_LEVEL_ERROR,
4477 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4478 return -EINVAL;
4479 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304480 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 +05304481 reason,
4482 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304483 global_operating_class,
4484 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304485 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304486 if (nla_put_s32(skb,
4487 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4488 state) ||
4489 nla_put_s32(skb,
4490 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4491 reason) ||
4492 nla_put_s32(skb,
4493 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4494 global_operating_class) ||
4495 nla_put_s32(skb,
4496 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4497 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304498
4499 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4500 goto nla_put_failure;
4501 }
4502
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304503 retVal = cfg80211_vendor_cmd_reply(skb);
4504 EXIT();
4505 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05304506
4507nla_put_failure:
4508 kfree_skb(skb);
4509 return -EINVAL;
4510}
4511
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304512static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4513 struct wireless_dev *wdev,
4514 const void *data,
4515 int data_len)
4516{
4517 int ret = 0;
4518
4519 vos_ssr_protect(__func__);
4520 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
4521 vos_ssr_unprotect(__func__);
4522
4523 return ret;
4524}
4525
Atul Mittal115287b2014-07-08 13:26:33 +05304526static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac,
4527 tANI_S32 state,
4528 tANI_S32 reason,
4529 void *ctx)
4530{
4531 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
4532 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4533 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304534 tANI_S32 global_operating_class = 0;
4535 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304536
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304537 ENTER();
4538
Atul Mittal115287b2014-07-08 13:26:33 +05304539 if (wlan_hdd_validate_context(pHddCtx)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304540 return -EINVAL;
4541 }
4542
4543 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4544
4545 return -ENOTSUPP;
4546 }
4547 skb = cfg80211_vendor_event_alloc(
4548 pHddCtx->wiphy,
4549 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4550 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4551 GFP_KERNEL);
4552
4553 if (!skb) {
4554 hddLog(VOS_TRACE_LEVEL_ERROR,
4555 FL("cfg80211_vendor_event_alloc failed"));
4556 return -EINVAL;
4557 }
4558 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304559 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4560 reason,
4561 state,
4562 global_operating_class,
4563 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304564 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4565 MAC_ADDR_ARRAY(mac));
4566
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304567 if (nla_put(skb,
4568 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4569 VOS_MAC_ADDR_SIZE, mac) ||
4570 nla_put_s32(skb,
4571 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4572 state) ||
4573 nla_put_s32(skb,
4574 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4575 reason) ||
4576 nla_put_s32(skb,
4577 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4578 channel) ||
4579 nla_put_s32(skb,
4580 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4581 global_operating_class)
4582 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304583 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4584 goto nla_put_failure;
4585 }
4586
4587 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304588 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05304589 return (0);
4590
4591nla_put_failure:
4592 kfree_skb(skb);
4593 return -EINVAL;
4594}
4595
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304596static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304597 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304598 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304599 int data_len)
4600{
4601 u8 peer[6] = {0};
4602 struct net_device *dev = wdev->netdev;
4603 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4604 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4605 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4606 eHalStatus status;
4607 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304608 int ret;
4609
4610 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304611
4612 status = wlan_hdd_validate_context(pHddCtx);
4613 if (0 != status) {
Atul Mittal115287b2014-07-08 13:26:33 +05304614 return -EINVAL;
4615 }
4616 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4617
4618 return -ENOTSUPP;
4619 }
4620 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4621 data, data_len,
4622 wlan_hdd_tdls_config_enable_policy)) {
4623 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4624 return -EINVAL;
4625 }
4626
4627 /* Parse and fetch mac address */
4628 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4629 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4630 return -EINVAL;
4631 }
4632
4633 memcpy(peer, nla_data(
4634 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4635 sizeof(peer));
4636 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4637
4638 /* Parse and fetch channel */
4639 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4640 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4641 return -EINVAL;
4642 }
4643 pReqMsg.channel = nla_get_s32(
4644 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4645 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4646
4647 /* Parse and fetch global operating class */
4648 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4649 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4650 return -EINVAL;
4651 }
4652 pReqMsg.global_operating_class = nla_get_s32(
4653 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4654 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4655 pReqMsg.global_operating_class);
4656
4657 /* Parse and fetch latency ms */
4658 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4660 return -EINVAL;
4661 }
4662 pReqMsg.max_latency_ms = nla_get_s32(
4663 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4664 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4665 pReqMsg.max_latency_ms);
4666
4667 /* Parse and fetch required bandwidth kbps */
4668 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4669 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4670 return -EINVAL;
4671 }
4672
4673 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4674 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4675 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4676 pReqMsg.min_bandwidth_kbps);
4677
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304678 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05304679 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05304680 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304681 wlan_hdd_cfg80211_exttdls_callback);
4682
4683 EXIT();
4684 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304685}
4686
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304687static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4688 struct wireless_dev *wdev,
4689 const void *data,
4690 int data_len)
4691{
4692 int ret = 0;
4693
4694 vos_ssr_protect(__func__);
4695 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
4696 vos_ssr_unprotect(__func__);
4697
4698 return ret;
4699}
4700
4701static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304702 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304703 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304704 int data_len)
4705{
4706 u8 peer[6] = {0};
4707 struct net_device *dev = wdev->netdev;
4708 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4709 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4710 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4711 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304712 int ret;
4713
4714 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304715
4716 status = wlan_hdd_validate_context(pHddCtx);
4717 if (0 != status) {
Atul Mittal115287b2014-07-08 13:26:33 +05304718 return -EINVAL;
4719 }
4720 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4721
4722 return -ENOTSUPP;
4723 }
4724 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4725 data, data_len,
4726 wlan_hdd_tdls_config_disable_policy)) {
4727 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4728 return -EINVAL;
4729 }
4730 /* Parse and fetch mac address */
4731 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4732 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4733 return -EINVAL;
4734 }
4735
4736 memcpy(peer, nla_data(
4737 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4738 sizeof(peer));
4739 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4740
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304741 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
4742
4743 EXIT();
4744 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304745}
4746
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304747static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4748 struct wireless_dev *wdev,
4749 const void *data,
4750 int data_len)
4751{
4752 int ret = 0;
4753
4754 vos_ssr_protect(__func__);
4755 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
4756 vos_ssr_unprotect(__func__);
4757
4758 return ret;
4759}
4760
Dasari Srinivas7875a302014-09-26 17:50:57 +05304761static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304762__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05304763 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304764 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05304765{
4766 struct net_device *dev = wdev->netdev;
4767 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4768 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4769 struct sk_buff *skb = NULL;
4770 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304771 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05304772
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304773 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304774
4775 ret = wlan_hdd_validate_context(pHddCtx);
4776 if (0 != ret)
4777 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304778 return ret;
4779 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05304780 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
4781 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
4782 fset |= WIFI_FEATURE_INFRA;
4783 }
4784
4785 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
4786 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
4787 fset |= WIFI_FEATURE_INFRA_5G;
4788 }
4789
4790#ifdef WLAN_FEATURE_P2P
4791 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
4792 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
4793 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
4794 fset |= WIFI_FEATURE_P2P;
4795 }
4796#endif
4797
4798 /* Soft-AP is supported currently by default */
4799 fset |= WIFI_FEATURE_SOFT_AP;
4800
4801#ifdef WLAN_FEATURE_EXTSCAN
4802 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
4803 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
4804 hddLog(LOG1, FL("EXTScan is supported by firmware"));
4805 fset |= WIFI_FEATURE_EXTSCAN;
4806 }
4807#endif
4808
4809#ifdef WLAN_FEATURE_NAN
4810 if (sme_IsFeatureSupportedByFW(NAN)) {
4811 hddLog(LOG1, FL("NAN is supported by firmware"));
4812 fset |= WIFI_FEATURE_NAN;
4813 }
4814#endif
4815
4816 /* D2D RTT is not supported currently by default */
4817 if (sme_IsFeatureSupportedByFW(RTT)) {
4818 hddLog(LOG1, FL("RTT is supported by firmware"));
4819 fset |= WIFI_FEATURE_D2AP_RTT;
4820 }
4821
4822#ifdef FEATURE_WLAN_BATCH_SCAN
4823 if (fset & WIFI_FEATURE_EXTSCAN) {
4824 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
4825 fset &= ~WIFI_FEATURE_BATCH_SCAN;
4826 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
4827 hddLog(LOG1, FL("Batch scan is supported by firmware"));
4828 fset |= WIFI_FEATURE_BATCH_SCAN;
4829 }
4830#endif
4831
4832#ifdef FEATURE_WLAN_SCAN_PNO
4833 if (pHddCtx->cfg_ini->configPNOScanSupport &&
4834 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
4835 hddLog(LOG1, FL("PNO is supported by firmware"));
4836 fset |= WIFI_FEATURE_PNO;
4837 }
4838#endif
4839
4840 /* STA+STA is supported currently by default */
4841 fset |= WIFI_FEATURE_ADDITIONAL_STA;
4842
4843#ifdef FEATURE_WLAN_TDLS
4844 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
4845 sme_IsFeatureSupportedByFW(TDLS)) {
4846 hddLog(LOG1, FL("TDLS is supported by firmware"));
4847 fset |= WIFI_FEATURE_TDLS;
4848 }
4849
4850 /* TDLS_OFFCHANNEL is not supported currently by default */
4851#endif
4852
4853#ifdef WLAN_AP_STA_CONCURRENCY
4854 /* AP+STA concurrency is supported currently by default */
4855 fset |= WIFI_FEATURE_AP_STA;
4856#endif
4857
4858 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
4859 NLMSG_HDRLEN);
4860
4861 if (!skb) {
4862 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4863 return -EINVAL;
4864 }
4865 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
4866
4867 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
4868 hddLog(LOGE, FL("nla put fail"));
4869 goto nla_put_failure;
4870 }
4871
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304872 ret = cfg80211_vendor_cmd_reply(skb);
4873 EXIT();
4874 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05304875
4876nla_put_failure:
4877 kfree_skb(skb);
4878 return -EINVAL;
4879}
4880
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304881static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304882wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
4883 struct wireless_dev *wdev,
4884 const void *data, int data_len)
4885{
4886 int ret = 0;
4887
4888 vos_ssr_protect(__func__);
4889 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
4890 vos_ssr_unprotect(__func__);
4891
4892 return ret;
4893}
4894
4895static int
4896__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304897 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304898 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304899{
4900 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
4901 uint8_t i, feature_sets, max_feature_sets;
4902 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
4903 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304904 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4905 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304906
4907 ENTER();
4908
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304909 ret = wlan_hdd_validate_context(pHddCtx);
4910 if (0 != ret)
4911 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304912 return ret;
4913 }
4914
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304915 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
4916 data, data_len, NULL)) {
4917 hddLog(LOGE, FL("Invalid ATTR"));
4918 return -EINVAL;
4919 }
4920
4921 /* Parse and fetch max feature set */
4922 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
4923 hddLog(LOGE, FL("Attr max feature set size failed"));
4924 return -EINVAL;
4925 }
4926 max_feature_sets = nla_get_u32(
4927 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
4928 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
4929
4930 /* Fill feature combination matrix */
4931 feature_sets = 0;
4932 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4933 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4934 WIFI_FEATURE_P2P;
4935
4936 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4937 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4938 WIFI_FEATURE_SOFT_AP;
4939
4940 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4941 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
4942 WIFI_FEATURE_SOFT_AP;
4943
4944 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4945 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4946 WIFI_FEATURE_SOFT_AP |
4947 WIFI_FEATURE_P2P;
4948
4949 /* Add more feature combinations here */
4950
4951 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
4952 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
4953 hddLog(LOG1, "Feature set matrix");
4954 for (i = 0; i < feature_sets; i++)
4955 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
4956
4957 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4958 sizeof(u32) * feature_sets +
4959 NLMSG_HDRLEN);
4960
4961 if (reply_skb) {
4962 if (nla_put_u32(reply_skb,
4963 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
4964 feature_sets) ||
4965 nla_put(reply_skb,
4966 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
4967 sizeof(u32) * feature_sets, feature_set_matrix)) {
4968 hddLog(LOGE, FL("nla put fail"));
4969 kfree_skb(reply_skb);
4970 return -EINVAL;
4971 }
4972
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304973 ret = cfg80211_vendor_cmd_reply(reply_skb);
4974 EXIT();
4975 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304976 }
4977 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
4978 return -ENOMEM;
4979
4980max_buffer_err:
4981 hddLog(LOGE, FL("Feature set max buffer size reached. feature_sets(%d) max(%d)"),
4982 feature_sets, WLAN_HDD_MAX_FEATURE_SET);
4983 return -EINVAL;
4984}
4985
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304986static int
4987wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
4988 struct wireless_dev *wdev,
4989 const void *data, int data_len)
4990{
4991 int ret = 0;
4992
4993 vos_ssr_protect(__func__);
4994 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
4995 data_len);
4996 vos_ssr_unprotect(__func__);
4997
4998 return ret;
4999}
5000
Agarwal Ashish738843c2014-09-25 12:27:56 +05305001static const struct nla_policy
5002wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5003 +1] =
5004{
5005 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5006};
5007
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305008static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305009 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305010 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305011 int data_len)
5012{
5013 struct net_device *dev = wdev->netdev;
5014 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5015 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5016 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5017 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5018 eHalStatus status;
5019 u32 dfsFlag = 0;
5020
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305021 ENTER();
5022
Agarwal Ashish738843c2014-09-25 12:27:56 +05305023 status = wlan_hdd_validate_context(pHddCtx);
5024 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305025 return -EINVAL;
5026 }
5027 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5028 data, data_len,
5029 wlan_hdd_set_no_dfs_flag_config_policy)) {
5030 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5031 return -EINVAL;
5032 }
5033
5034 /* Parse and fetch required bandwidth kbps */
5035 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5036 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5037 return -EINVAL;
5038 }
5039
5040 dfsFlag = nla_get_u32(
5041 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5042 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5043 dfsFlag);
5044
5045 pHddCtx->disable_dfs_flag = dfsFlag;
5046
5047 sme_disable_dfs_channel(hHal, dfsFlag);
5048 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305049
5050 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305051 return 0;
5052}
Atul Mittal115287b2014-07-08 13:26:33 +05305053
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305054static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5055 struct wireless_dev *wdev,
5056 const void *data,
5057 int data_len)
5058{
5059 int ret = 0;
5060
5061 vos_ssr_protect(__func__);
5062 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5063 vos_ssr_unprotect(__func__);
5064
5065 return ret;
5066
5067}
5068
Mukul Sharma2a271632014-10-13 14:59:01 +05305069const struct
5070nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5071{
5072 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5073 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5074};
5075
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305076static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305077 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305078{
5079
5080 u8 bssid[6] = {0};
5081 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5082 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5083 eHalStatus status = eHAL_STATUS_SUCCESS;
5084 v_U32_t isFwrRoamEnabled = FALSE;
5085 int ret;
5086
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305087 ENTER();
5088
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305089 ret = wlan_hdd_validate_context(pHddCtx);
5090 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305091 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305092 }
5093
5094 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5095 data, data_len,
5096 qca_wlan_vendor_attr);
5097 if (ret){
5098 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5099 return -EINVAL;
5100 }
5101
5102 /* Parse and fetch Enable flag */
5103 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5104 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5105 return -EINVAL;
5106 }
5107
5108 isFwrRoamEnabled = nla_get_u32(
5109 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5110
5111 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5112
5113 /* Parse and fetch bssid */
5114 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5115 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5116 return -EINVAL;
5117 }
5118
5119 memcpy(bssid, nla_data(
5120 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5121 sizeof(bssid));
5122 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5123
5124 //Update roaming
5125 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305126 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305127 return status;
5128}
5129
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305130static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5131 struct wireless_dev *wdev, const void *data, int data_len)
5132{
5133 int ret = 0;
5134
5135 vos_ssr_protect(__func__);
5136 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5137 vos_ssr_unprotect(__func__);
5138
5139 return ret;
5140}
5141
Sunil Duttc69bccb2014-05-26 21:30:20 +05305142const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
5143{
Mukul Sharma2a271632014-10-13 14:59:01 +05305144 {
5145 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5146 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
5147 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5148 WIPHY_VENDOR_CMD_NEED_NETDEV |
5149 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305150 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05305151 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305152#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5153 {
5154 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5155 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
5156 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5157 WIPHY_VENDOR_CMD_NEED_NETDEV |
5158 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305159 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05305160 },
5161
5162 {
5163 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5164 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
5165 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5166 WIPHY_VENDOR_CMD_NEED_NETDEV |
5167 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305168 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05305169 },
5170
5171 {
5172 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5173 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
5174 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5175 WIPHY_VENDOR_CMD_NEED_NETDEV |
5176 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305177 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05305178 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305179#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305180#ifdef WLAN_FEATURE_EXTSCAN
5181 {
5182 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5183 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
5184 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5185 WIPHY_VENDOR_CMD_NEED_NETDEV |
5186 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305187 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05305188 },
5189 {
5190 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5191 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
5192 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5193 WIPHY_VENDOR_CMD_NEED_NETDEV |
5194 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305195 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05305196 },
5197 {
5198 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5199 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
5200 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5201 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305202 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05305203 },
5204 {
5205 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5206 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
5207 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5208 WIPHY_VENDOR_CMD_NEED_NETDEV |
5209 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305210 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05305211 },
5212 {
5213 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5214 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
5215 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5216 WIPHY_VENDOR_CMD_NEED_NETDEV |
5217 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305218 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05305219 },
5220 {
5221 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5222 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
5223 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5224 WIPHY_VENDOR_CMD_NEED_NETDEV |
5225 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305226 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305227 },
5228 {
5229 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5230 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
5231 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5232 WIPHY_VENDOR_CMD_NEED_NETDEV |
5233 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305234 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305235 },
5236 {
5237 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5238 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
5239 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5240 WIPHY_VENDOR_CMD_NEED_NETDEV |
5241 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305242 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305243 },
5244 {
5245 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5246 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
5247 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5248 WIPHY_VENDOR_CMD_NEED_NETDEV |
5249 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305250 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305251 },
5252#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305253/*EXT TDLS*/
5254 {
5255 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5256 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
5257 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5258 WIPHY_VENDOR_CMD_NEED_NETDEV |
5259 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305260 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05305261 },
5262 {
5263 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5264 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
5265 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5266 WIPHY_VENDOR_CMD_NEED_NETDEV |
5267 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305268 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05305269 },
5270 {
5271 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5272 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
5273 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5274 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305275 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05305276 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05305277 {
5278 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5279 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
5280 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5281 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305282 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05305283 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05305284 {
5285 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5286 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
5287 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5288 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305289 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05305290 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305291 {
5292 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5293 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
5294 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5295 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305296 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305297 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305298 {
5299 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5300 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
5301 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5302 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305303 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305304 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305305};
5306
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005307/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05305308static const
5309struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005310{
5311#ifdef FEATURE_WLAN_CH_AVOID
5312 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05305313 .vendor_id = QCA_NL80211_VENDOR_ID,
5314 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005315 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305316#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
5317#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5318 {
5319 /* Index = 1*/
5320 .vendor_id = QCA_NL80211_VENDOR_ID,
5321 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
5322 },
5323 {
5324 /* Index = 2*/
5325 .vendor_id = QCA_NL80211_VENDOR_ID,
5326 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
5327 },
5328 {
5329 /* Index = 3*/
5330 .vendor_id = QCA_NL80211_VENDOR_ID,
5331 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
5332 },
5333 {
5334 /* Index = 4*/
5335 .vendor_id = QCA_NL80211_VENDOR_ID,
5336 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
5337 },
5338 {
5339 /* Index = 5*/
5340 .vendor_id = QCA_NL80211_VENDOR_ID,
5341 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
5342 },
5343 {
5344 /* Index = 6*/
5345 .vendor_id = QCA_NL80211_VENDOR_ID,
5346 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
5347 },
5348#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305349#ifdef WLAN_FEATURE_EXTSCAN
5350 {
5351 .vendor_id = QCA_NL80211_VENDOR_ID,
5352 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
5353 },
5354 {
5355 .vendor_id = QCA_NL80211_VENDOR_ID,
5356 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
5357 },
5358 {
5359 .vendor_id = QCA_NL80211_VENDOR_ID,
5360 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
5361 },
5362 {
5363 .vendor_id = QCA_NL80211_VENDOR_ID,
5364 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
5365 },
5366 {
5367 .vendor_id = QCA_NL80211_VENDOR_ID,
5368 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
5369 },
5370 {
5371 .vendor_id = QCA_NL80211_VENDOR_ID,
5372 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
5373 },
5374 {
5375 .vendor_id = QCA_NL80211_VENDOR_ID,
5376 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
5377 },
5378 {
5379 .vendor_id = QCA_NL80211_VENDOR_ID,
5380 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
5381 },
5382 {
5383 .vendor_id = QCA_NL80211_VENDOR_ID,
5384 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
5385 },
5386 {
5387 .vendor_id = QCA_NL80211_VENDOR_ID,
5388 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
5389 },
5390 {
5391 .vendor_id = QCA_NL80211_VENDOR_ID,
5392 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
5393 },
5394 {
5395 .vendor_id = QCA_NL80211_VENDOR_ID,
5396 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
5397 },
5398 {
5399 .vendor_id = QCA_NL80211_VENDOR_ID,
5400 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
5401 },
5402#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305403/*EXT TDLS*/
5404 {
5405 .vendor_id = QCA_NL80211_VENDOR_ID,
5406 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
5407 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005408};
5409
Jeff Johnson295189b2012-06-20 16:38:30 -07005410/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305411 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305412 * This function is called by hdd_wlan_startup()
5413 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305414 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07005415 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305416struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07005417{
5418 struct wiphy *wiphy;
5419 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305420 /*
5421 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07005422 */
5423 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
5424
5425 if (!wiphy)
5426 {
5427 /* Print error and jump into err label and free the memory */
5428 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
5429 return NULL;
5430 }
5431
Sunil Duttc69bccb2014-05-26 21:30:20 +05305432
Jeff Johnson295189b2012-06-20 16:38:30 -07005433 return wiphy;
5434}
5435
5436/*
5437 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305438 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07005439 * private ioctl to change the band value
5440 */
5441int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
5442{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305443 int i, j;
5444 eNVChannelEnabledType channelEnabledState;
5445
Jeff Johnsone7245742012-09-05 17:12:55 -07005446 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305447
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305448 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005449 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305450
5451 if (NULL == wiphy->bands[i])
5452 {
5453 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5454 __func__, i);
5455 continue;
5456 }
5457
5458 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5459 {
5460 struct ieee80211_supported_band *band = wiphy->bands[i];
5461
5462 channelEnabledState = vos_nv_getChannelEnabledState(
5463 band->channels[j].hw_value);
5464
5465 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
5466 {
Abhishek Singh678227a2014-11-04 10:52:38 +05305467 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305468 continue;
5469 }
5470 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
5471 {
5472 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5473 continue;
5474 }
5475
5476 if (NV_CHANNEL_DISABLE == channelEnabledState ||
5477 NV_CHANNEL_INVALID == channelEnabledState)
5478 {
5479 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5480 }
5481 else if (NV_CHANNEL_DFS == channelEnabledState)
5482 {
5483 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5484 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
5485 }
5486 else
5487 {
5488 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
5489 |IEEE80211_CHAN_RADAR);
5490 }
5491 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005492 }
5493 return 0;
5494}
5495/*
5496 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305497 * This function is called by hdd_wlan_startup()
5498 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005499 * This function is used to initialize and register wiphy structure.
5500 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305501int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005502 struct wiphy *wiphy,
5503 hdd_config_t *pCfg
5504 )
5505{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305506 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305507 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5508
Jeff Johnsone7245742012-09-05 17:12:55 -07005509 ENTER();
5510
Jeff Johnson295189b2012-06-20 16:38:30 -07005511 /* Now bind the underlying wlan device with wiphy */
5512 set_wiphy_dev(wiphy, dev);
5513
5514 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005515
Kiet Lam6c583332013-10-14 05:37:09 +05305516#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005517 /* the flag for the other case would be initialzed in
5518 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005519 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305520#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005521
Amar Singhalfddc28c2013-09-05 13:03:40 -07005522 /* This will disable updating of NL channels from passive to
5523 * active if a beacon is received on passive channel. */
5524 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07005525
Amar Singhalfddc28c2013-09-05 13:03:40 -07005526
Amar Singhala49cbc52013-10-08 18:37:44 -07005527
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005528#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005529 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5530 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5531 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005532 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05305533 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005534#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005535
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005536#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005537 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005538#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005539 || pCfg->isFastRoamIniFeatureEnabled
5540#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005541#ifdef FEATURE_WLAN_ESE
5542 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005543#endif
5544 )
5545 {
5546 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5547 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005548#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005549#ifdef FEATURE_WLAN_TDLS
5550 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5551 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5552#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305553#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305554 if (pCfg->configPNOScanSupport)
5555 {
5556 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5557 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5558 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5559 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5560 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305561#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005562
Amar Singhalfddc28c2013-09-05 13:03:40 -07005563#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005564 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5565 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005566 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005567 driver need to determine what to do with both
5568 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005569
5570 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005571#else
5572 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005573#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005574
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305575 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5576
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05305577 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005578
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305579 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5580
Jeff Johnson295189b2012-06-20 16:38:30 -07005581 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305582 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07005583 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07005584 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5585 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005586 | BIT(NL80211_IFTYPE_AP);
5587
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305588 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005589 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305590#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5591 if( pCfg->enableMCC )
5592 {
5593 /* Currently, supports up to two channels */
5594 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005595
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305596 if( !pCfg->allowMCCGODiffBI )
5597 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005598
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305599 }
5600 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5601 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005602#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305603 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005604
Jeff Johnson295189b2012-06-20 16:38:30 -07005605 /* Before registering we need to update the ht capabilitied based
5606 * on ini values*/
5607 if( !pCfg->ShortGI20MhzEnable )
5608 {
5609 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5610 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5611 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5612 }
5613
5614 if( !pCfg->ShortGI40MhzEnable )
5615 {
5616 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5617 }
5618
5619 if( !pCfg->nChannelBondingMode5GHz )
5620 {
5621 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5622 }
5623
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305624 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305625 if (true == hdd_is_5g_supported(pHddCtx))
5626 {
5627 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5628 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305629
5630 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5631 {
5632
5633 if (NULL == wiphy->bands[i])
5634 {
5635 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5636 __func__, i);
5637 continue;
5638 }
5639
5640 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5641 {
5642 struct ieee80211_supported_band *band = wiphy->bands[i];
5643
5644 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5645 {
5646 // Enable social channels for P2P
5647 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5648 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5649 else
5650 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5651 continue;
5652 }
5653 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5654 {
5655 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5656 continue;
5657 }
5658 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005659 }
5660 /*Initialise the supported cipher suite details*/
5661 wiphy->cipher_suites = hdd_cipher_suites;
5662 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5663
5664 /*signal strength in mBm (100*dBm) */
5665 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5666
5667#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305668 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005669#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005670
Sunil Duttc69bccb2014-05-26 21:30:20 +05305671 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
5672 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005673 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
5674 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
5675
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305676 EXIT();
5677 return 0;
5678}
5679
5680/* In this function we are registering wiphy. */
5681int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
5682{
5683 ENTER();
5684 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005685 if (0 > wiphy_register(wiphy))
5686 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305687 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07005688 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
5689 return -EIO;
5690 }
5691
5692 EXIT();
5693 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305694}
Jeff Johnson295189b2012-06-20 16:38:30 -07005695
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305696/* In this function we are updating channel list when,
5697 regulatory domain is FCC and country code is US.
5698 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
5699 As per FCC smart phone is not a indoor device.
5700 GO should not opeate on indoor channels */
5701void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
5702{
5703 int j;
5704 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5705 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
5706 //Default counrtycode from NV at the time of wiphy initialization.
5707 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
5708 &defaultCountryCode[0]))
5709 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005710 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305711 }
5712 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
5713 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305714 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
5715 {
5716 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
5717 return;
5718 }
5719 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
5720 {
5721 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
5722 // Mark UNII -1 band channel as passive
5723 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
5724 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
5725 }
5726 }
5727}
5728
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305729/* This function registers for all frame which supplicant is interested in */
5730void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005731{
Jeff Johnson295189b2012-06-20 16:38:30 -07005732 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5733 /* Register for all P2P action, public action etc frames */
5734 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5735
Jeff Johnsone7245742012-09-05 17:12:55 -07005736 ENTER();
5737
Jeff Johnson295189b2012-06-20 16:38:30 -07005738 /* Right now we are registering these frame when driver is getting
5739 initialized. Once we will move to 2.6.37 kernel, in which we have
5740 frame register ops, we will move this code as a part of that */
5741 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305742 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07005743 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5744
5745 /* GAS Initial Response */
5746 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5747 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305748
Jeff Johnson295189b2012-06-20 16:38:30 -07005749 /* GAS Comeback Request */
5750 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5751 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5752
5753 /* GAS Comeback Response */
5754 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5755 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5756
5757 /* P2P Public Action */
5758 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305759 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005760 P2P_PUBLIC_ACTION_FRAME_SIZE );
5761
5762 /* P2P Action */
5763 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5764 (v_U8_t*)P2P_ACTION_FRAME,
5765 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07005766
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05305767 /* WNM BSS Transition Request frame */
5768 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5769 (v_U8_t*)WNM_BSS_ACTION_FRAME,
5770 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005771
5772 /* WNM-Notification */
5773 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5774 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5775 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005776}
5777
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305778void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005779{
Jeff Johnson295189b2012-06-20 16:38:30 -07005780 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5781 /* Register for all P2P action, public action etc frames */
5782 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5783
Jeff Johnsone7245742012-09-05 17:12:55 -07005784 ENTER();
5785
Jeff Johnson295189b2012-06-20 16:38:30 -07005786 /* Right now we are registering these frame when driver is getting
5787 initialized. Once we will move to 2.6.37 kernel, in which we have
5788 frame register ops, we will move this code as a part of that */
5789 /* GAS Initial Request */
5790
5791 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5792 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5793
5794 /* GAS Initial Response */
5795 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5796 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305797
Jeff Johnson295189b2012-06-20 16:38:30 -07005798 /* GAS Comeback Request */
5799 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5800 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5801
5802 /* GAS Comeback Response */
5803 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5804 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5805
5806 /* P2P Public Action */
5807 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305808 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005809 P2P_PUBLIC_ACTION_FRAME_SIZE );
5810
5811 /* P2P Action */
5812 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5813 (v_U8_t*)P2P_ACTION_FRAME,
5814 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005815 /* WNM-Notification */
5816 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5817 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5818 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005819}
5820
5821#ifdef FEATURE_WLAN_WAPI
5822void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
5823 const u8 *mac_addr, u8 *key , int key_Len)
5824{
5825 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5826 tCsrRoamSetKey setKey;
5827 v_BOOL_t isConnected = TRUE;
5828 int status = 0;
5829 v_U32_t roamId= 0xFF;
5830 tANI_U8 *pKeyPtr = NULL;
5831 int n = 0;
5832
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305833 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
5834 __func__, hdd_device_modetoString(pAdapter->device_mode),
5835 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005836
Gopichand Nakkalae7480202013-02-11 15:24:22 +05305837 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005838 setKey.keyId = key_index; // Store Key ID
5839 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
5840 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
5841 setKey.paeRole = 0 ; // the PAE role
5842 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
5843 {
5844 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
5845 }
5846 else
5847 {
5848 isConnected = hdd_connIsConnected(pHddStaCtx);
5849 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
5850 }
5851 setKey.keyLength = key_Len;
5852 pKeyPtr = setKey.Key;
5853 memcpy( pKeyPtr, key, key_Len);
5854
Arif Hussain6d2a3322013-11-17 19:50:10 -08005855 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005856 __func__, key_Len);
5857 for (n = 0 ; n < key_Len; n++)
5858 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
5859 __func__,n,setKey.Key[n]);
5860
5861 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
5862 if ( isConnected )
5863 {
5864 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
5865 pAdapter->sessionId, &setKey, &roamId );
5866 }
5867 if ( status != 0 )
5868 {
5869 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5870 "[%4d] sme_RoamSetKey returned ERROR status= %d",
5871 __LINE__, status );
5872 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
5873 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05305874 /* Need to clear any trace of key value in the memory.
5875 * Thus zero out the memory even though it is local
5876 * variable.
5877 */
5878 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005879}
5880#endif /* FEATURE_WLAN_WAPI*/
5881
5882#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305883int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005884 beacon_data_t **ppBeacon,
5885 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005886#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305887int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005888 beacon_data_t **ppBeacon,
5889 struct cfg80211_beacon_data *params,
5890 int dtim_period)
5891#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305892{
Jeff Johnson295189b2012-06-20 16:38:30 -07005893 int size;
5894 beacon_data_t *beacon = NULL;
5895 beacon_data_t *old = NULL;
5896 int head_len,tail_len;
5897
Jeff Johnsone7245742012-09-05 17:12:55 -07005898 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005899 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305900 {
5901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5902 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005903 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305904 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005905
5906 old = pAdapter->sessionCtx.ap.beacon;
5907
5908 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305909 {
5910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5911 FL("session(%d) old and new heads points to NULL"),
5912 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005913 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305914 }
5915
5916 if (params->tail && !params->tail_len)
5917 {
5918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5919 FL("tail_len is zero but tail is not NULL"));
5920 return -EINVAL;
5921 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005922
Jeff Johnson295189b2012-06-20 16:38:30 -07005923#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
5924 /* Kernel 3.0 is not updating dtim_period for set beacon */
5925 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305926 {
5927 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5928 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005929 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305930 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005931#endif
5932
5933 if(params->head)
5934 head_len = params->head_len;
5935 else
5936 head_len = old->head_len;
5937
5938 if(params->tail || !old)
5939 tail_len = params->tail_len;
5940 else
5941 tail_len = old->tail_len;
5942
5943 size = sizeof(beacon_data_t) + head_len + tail_len;
5944
5945 beacon = kzalloc(size, GFP_KERNEL);
5946
5947 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305948 {
5949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5950 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005951 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305952 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005953
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005954#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005955 if(params->dtim_period || !old )
5956 beacon->dtim_period = params->dtim_period;
5957 else
5958 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005959#else
5960 if(dtim_period || !old )
5961 beacon->dtim_period = dtim_period;
5962 else
5963 beacon->dtim_period = old->dtim_period;
5964#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305965
Jeff Johnson295189b2012-06-20 16:38:30 -07005966 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
5967 beacon->tail = beacon->head + head_len;
5968 beacon->head_len = head_len;
5969 beacon->tail_len = tail_len;
5970
5971 if(params->head) {
5972 memcpy (beacon->head,params->head,beacon->head_len);
5973 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305974 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07005975 if(old)
5976 memcpy (beacon->head,old->head,beacon->head_len);
5977 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305978
Jeff Johnson295189b2012-06-20 16:38:30 -07005979 if(params->tail) {
5980 memcpy (beacon->tail,params->tail,beacon->tail_len);
5981 }
5982 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305983 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07005984 memcpy (beacon->tail,old->tail,beacon->tail_len);
5985 }
5986
5987 *ppBeacon = beacon;
5988
5989 kfree(old);
5990
5991 return 0;
5992
5993}
Jeff Johnson295189b2012-06-20 16:38:30 -07005994
5995v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
5996{
5997 int left = length;
5998 v_U8_t *ptr = pIes;
5999 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306000
Jeff Johnson295189b2012-06-20 16:38:30 -07006001 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306002 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006003 elem_id = ptr[0];
6004 elem_len = ptr[1];
6005 left -= 2;
6006 if(elem_len > left)
6007 {
6008 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006009 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006010 eid,elem_len,left);
6011 return NULL;
6012 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306013 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006014 {
6015 return ptr;
6016 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306017
Jeff Johnson295189b2012-06-20 16:38:30 -07006018 left -= elem_len;
6019 ptr += (elem_len + 2);
6020 }
6021 return NULL;
6022}
6023
Jeff Johnson295189b2012-06-20 16:38:30 -07006024/* Check if rate is 11g rate or not */
6025static int wlan_hdd_rate_is_11g(u8 rate)
6026{
Sanjay Devnani28322e22013-06-21 16:13:40 -07006027 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006028 u8 i;
6029 for (i = 0; i < 8; i++)
6030 {
6031 if(rate == gRateArray[i])
6032 return TRUE;
6033 }
6034 return FALSE;
6035}
6036
6037/* Check for 11g rate and set proper 11g only mode */
6038static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
6039 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
6040{
6041 u8 i, num_rates = pIe[0];
6042
6043 pIe += 1;
6044 for ( i = 0; i < num_rates; i++)
6045 {
6046 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
6047 {
6048 /* If rate set have 11g rate than change the mode to 11G */
6049 *pSapHw_mode = eSAP_DOT11_MODE_11g;
6050 if (pIe[i] & BASIC_RATE_MASK)
6051 {
6052 /* If we have 11g rate as basic rate, it means mode
6053 is 11g only mode.
6054 */
6055 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
6056 *pCheckRatesfor11g = FALSE;
6057 }
6058 }
6059 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6060 {
6061 *require_ht = TRUE;
6062 }
6063 }
6064 return;
6065}
6066
6067static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
6068{
6069 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6070 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6071 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6072 u8 checkRatesfor11g = TRUE;
6073 u8 require_ht = FALSE;
6074 u8 *pIe=NULL;
6075
6076 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
6077
6078 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6079 pBeacon->head_len, WLAN_EID_SUPP_RATES);
6080 if (pIe != NULL)
6081 {
6082 pIe += 1;
6083 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6084 &pConfig->SapHw_mode);
6085 }
6086
6087 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6088 WLAN_EID_EXT_SUPP_RATES);
6089 if (pIe != NULL)
6090 {
6091
6092 pIe += 1;
6093 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6094 &pConfig->SapHw_mode);
6095 }
6096
6097 if( pConfig->channel > 14 )
6098 {
6099 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
6100 }
6101
6102 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6103 WLAN_EID_HT_CAPABILITY);
6104
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306105 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006106 {
6107 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
6108 if(require_ht)
6109 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
6110 }
6111}
6112
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306113static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
6114 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
6115{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006116 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306117 v_U8_t *pIe = NULL;
6118 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6119
6120 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6121 pBeacon->tail, pBeacon->tail_len);
6122
6123 if (pIe)
6124 {
6125 ielen = pIe[1] + 2;
6126 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6127 {
6128 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
6129 }
6130 else
6131 {
6132 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
6133 return -EINVAL;
6134 }
6135 *total_ielen += ielen;
6136 }
6137 return 0;
6138}
6139
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006140static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
6141 v_U8_t *genie, v_U8_t *total_ielen)
6142{
6143 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6144 int left = pBeacon->tail_len;
6145 v_U8_t *ptr = pBeacon->tail;
6146 v_U8_t elem_id, elem_len;
6147 v_U16_t ielen = 0;
6148
6149 if ( NULL == ptr || 0 == left )
6150 return;
6151
6152 while (left >= 2)
6153 {
6154 elem_id = ptr[0];
6155 elem_len = ptr[1];
6156 left -= 2;
6157 if (elem_len > left)
6158 {
6159 hddLog( VOS_TRACE_LEVEL_ERROR,
6160 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
6161 elem_id, elem_len, left);
6162 return;
6163 }
6164 if (IE_EID_VENDOR == elem_id)
6165 {
6166 /* skipping the VSIE's which we don't want to include or
6167 * it will be included by existing code
6168 */
6169 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
6170#ifdef WLAN_FEATURE_WFD
6171 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
6172#endif
6173 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6174 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6175 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
6176 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6177 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
6178 {
6179 ielen = ptr[1] + 2;
6180 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6181 {
6182 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
6183 *total_ielen += ielen;
6184 }
6185 else
6186 {
6187 hddLog( VOS_TRACE_LEVEL_ERROR,
6188 "IE Length is too big "
6189 "IEs eid=%d elem_len=%d total_ie_lent=%d",
6190 elem_id, elem_len, *total_ielen);
6191 }
6192 }
6193 }
6194
6195 left -= elem_len;
6196 ptr += (elem_len + 2);
6197 }
6198 return;
6199}
6200
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006201#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006202static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6203 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006204#else
6205static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6206 struct cfg80211_beacon_data *params)
6207#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006208{
6209 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306210 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006211 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07006212 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006213
6214 genie = vos_mem_malloc(MAX_GENIE_LEN);
6215
6216 if(genie == NULL) {
6217
6218 return -ENOMEM;
6219 }
6220
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306221 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6222 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006223 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306224 hddLog(LOGE,
6225 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306226 ret = -EINVAL;
6227 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006228 }
6229
6230#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306231 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6232 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
6233 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306234 hddLog(LOGE,
6235 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306236 ret = -EINVAL;
6237 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006238 }
6239#endif
6240
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306241 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6242 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006243 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306244 hddLog(LOGE,
6245 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306246 ret = -EINVAL;
6247 goto done;
6248 }
6249
6250 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
6251 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006252 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07006253 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006254
6255 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6256 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
6257 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6258 {
6259 hddLog(LOGE,
6260 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006261 ret = -EINVAL;
6262 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006263 }
6264
6265 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6266 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6267 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6268 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6269 ==eHAL_STATUS_FAILURE)
6270 {
6271 hddLog(LOGE,
6272 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006273 ret = -EINVAL;
6274 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006275 }
6276
6277 // Added for ProResp IE
6278 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
6279 {
6280 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
6281 u8 probe_rsp_ie_len[3] = {0};
6282 u8 counter = 0;
6283 /* Check Probe Resp Length if it is greater then 255 then Store
6284 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
6285 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
6286 Store More then 255 bytes into One Variable.
6287 */
6288 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6289 {
6290 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6291 {
6292 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6293 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6294 }
6295 else
6296 {
6297 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6298 rem_probe_resp_ie_len = 0;
6299 }
6300 }
6301
6302 rem_probe_resp_ie_len = 0;
6303
6304 if (probe_rsp_ie_len[0] > 0)
6305 {
6306 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6307 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6308 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6309 probe_rsp_ie_len[0], NULL,
6310 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6311 {
6312 hddLog(LOGE,
6313 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006314 ret = -EINVAL;
6315 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006316 }
6317 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6318 }
6319
6320 if (probe_rsp_ie_len[1] > 0)
6321 {
6322 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6323 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6324 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6325 probe_rsp_ie_len[1], NULL,
6326 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6327 {
6328 hddLog(LOGE,
6329 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006330 ret = -EINVAL;
6331 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006332 }
6333 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6334 }
6335
6336 if (probe_rsp_ie_len[2] > 0)
6337 {
6338 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6339 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6340 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6341 probe_rsp_ie_len[2], NULL,
6342 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6343 {
6344 hddLog(LOGE,
6345 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006346 ret = -EINVAL;
6347 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006348 }
6349 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6350 }
6351
6352 if (probe_rsp_ie_len[1] == 0 )
6353 {
6354 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6355 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6356 eANI_BOOLEAN_FALSE) )
6357 {
6358 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006359 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006360 }
6361 }
6362
6363 if (probe_rsp_ie_len[2] == 0 )
6364 {
6365 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6366 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6367 eANI_BOOLEAN_FALSE) )
6368 {
6369 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006370 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006371 }
6372 }
6373
6374 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6375 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6376 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6377 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6378 == eHAL_STATUS_FAILURE)
6379 {
6380 hddLog(LOGE,
6381 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006382 ret = -EINVAL;
6383 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006384 }
6385 }
6386 else
6387 {
6388 // Reset WNI_CFG_PROBE_RSP Flags
6389 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
6390
6391 hddLog(VOS_TRACE_LEVEL_INFO,
6392 "%s: No Probe Response IE received in set beacon",
6393 __func__);
6394 }
6395
6396 // Added for AssocResp IE
6397 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
6398 {
6399 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6400 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
6401 params->assocresp_ies_len, NULL,
6402 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6403 {
6404 hddLog(LOGE,
6405 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006406 ret = -EINVAL;
6407 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006408 }
6409
6410 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6411 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
6412 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6413 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6414 == eHAL_STATUS_FAILURE)
6415 {
6416 hddLog(LOGE,
6417 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006418 ret = -EINVAL;
6419 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006420 }
6421 }
6422 else
6423 {
6424 hddLog(VOS_TRACE_LEVEL_INFO,
6425 "%s: No Assoc Response IE received in set beacon",
6426 __func__);
6427
6428 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6429 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6430 eANI_BOOLEAN_FALSE) )
6431 {
6432 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006433 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006434 }
6435 }
6436
Jeff Johnsone7245742012-09-05 17:12:55 -07006437done:
Jeff Johnson295189b2012-06-20 16:38:30 -07006438 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306439 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006440}
Jeff Johnson295189b2012-06-20 16:38:30 -07006441
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306442/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 * FUNCTION: wlan_hdd_validate_operation_channel
6444 * called by wlan_hdd_cfg80211_start_bss() and
6445 * wlan_hdd_cfg80211_set_channel()
6446 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306447 * channel list.
6448 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006449VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006450{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306451
Jeff Johnson295189b2012-06-20 16:38:30 -07006452 v_U32_t num_ch = 0;
6453 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6454 u32 indx = 0;
6455 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306456 v_U8_t fValidChannel = FALSE, count = 0;
6457 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306458
Jeff Johnson295189b2012-06-20 16:38:30 -07006459 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6460
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306461 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006462 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306463 /* Validate the channel */
6464 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006465 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306466 if ( channel == rfChannels[count].channelNum )
6467 {
6468 fValidChannel = TRUE;
6469 break;
6470 }
6471 }
6472 if (fValidChannel != TRUE)
6473 {
6474 hddLog(VOS_TRACE_LEVEL_ERROR,
6475 "%s: Invalid Channel [%d]", __func__, channel);
6476 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006477 }
6478 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306479 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006480 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306481 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6482 valid_ch, &num_ch))
6483 {
6484 hddLog(VOS_TRACE_LEVEL_ERROR,
6485 "%s: failed to get valid channel list", __func__);
6486 return VOS_STATUS_E_FAILURE;
6487 }
6488 for (indx = 0; indx < num_ch; indx++)
6489 {
6490 if (channel == valid_ch[indx])
6491 {
6492 break;
6493 }
6494 }
6495
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306496 if (indx >= num_ch)
6497 {
6498 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6499 {
6500 eCsrBand band;
6501 unsigned int freq;
6502
6503 sme_GetFreqBand(hHal, &band);
6504
6505 if (eCSR_BAND_5G == band)
6506 {
6507#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6508 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6509 {
6510 freq = ieee80211_channel_to_frequency(channel,
6511 IEEE80211_BAND_2GHZ);
6512 }
6513 else
6514 {
6515 freq = ieee80211_channel_to_frequency(channel,
6516 IEEE80211_BAND_5GHZ);
6517 }
6518#else
6519 freq = ieee80211_channel_to_frequency(channel);
6520#endif
6521 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6522 return VOS_STATUS_SUCCESS;
6523 }
6524 }
6525
6526 hddLog(VOS_TRACE_LEVEL_ERROR,
6527 "%s: Invalid Channel [%d]", __func__, channel);
6528 return VOS_STATUS_E_FAILURE;
6529 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006530 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306531
Jeff Johnson295189b2012-06-20 16:38:30 -07006532 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306533
Jeff Johnson295189b2012-06-20 16:38:30 -07006534}
6535
Viral Modi3a32cc52013-02-08 11:14:52 -08006536/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306537 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08006538 * This function is used to set the channel number
6539 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306540static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08006541 struct ieee80211_channel *chan,
6542 enum nl80211_channel_type channel_type
6543 )
6544{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306545 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006546 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006547 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006548 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306549 hdd_context_t *pHddCtx;
6550 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006551
6552 ENTER();
6553
6554 if( NULL == dev )
6555 {
6556 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006557 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006558 return -ENODEV;
6559 }
6560 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306561
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306562 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6563 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6564 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006565 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306566 "%s: device_mode = %s (%d) freq = %d", __func__,
6567 hdd_device_modetoString(pAdapter->device_mode),
6568 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306569
6570 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6571 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306572 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006573 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306574 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006575 }
6576
6577 /*
6578 * Do freq to chan conversion
6579 * TODO: for 11a
6580 */
6581
6582 channel = ieee80211_frequency_to_channel(freq);
6583
6584 /* Check freq range */
6585 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6586 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6587 {
6588 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006589 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006590 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6591 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6592 return -EINVAL;
6593 }
6594
6595 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6596
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306597 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6598 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006599 {
6600 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6601 {
6602 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006603 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006604 return -EINVAL;
6605 }
6606 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6607 "%s: set channel to [%d] for device mode =%d",
6608 __func__, channel,pAdapter->device_mode);
6609 }
6610 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006611 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006612 )
6613 {
6614 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6615 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6616 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6617
6618 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6619 {
6620 /* Link is up then return cant set channel*/
6621 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006622 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006623 return -EINVAL;
6624 }
6625
6626 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6627 pHddStaCtx->conn_info.operationChannel = channel;
6628 pRoamProfile->ChannelInfo.ChannelList =
6629 &pHddStaCtx->conn_info.operationChannel;
6630 }
6631 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006632 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006633 )
6634 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306635 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6636 {
6637 if(VOS_STATUS_SUCCESS !=
6638 wlan_hdd_validate_operation_channel(pAdapter,channel))
6639 {
6640 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006641 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306642 return -EINVAL;
6643 }
6644 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6645 }
6646 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006647 {
6648 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6649
6650 /* If auto channel selection is configured as enable/ 1 then ignore
6651 channel set by supplicant
6652 */
6653 if ( cfg_param->apAutoChannelSelection )
6654 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306655 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6656 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006657 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306658 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6659 __func__, hdd_device_modetoString(pAdapter->device_mode),
6660 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006661 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306662 else
6663 {
6664 if(VOS_STATUS_SUCCESS !=
6665 wlan_hdd_validate_operation_channel(pAdapter,channel))
6666 {
6667 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006668 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306669 return -EINVAL;
6670 }
6671 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6672 }
Viral Modi3a32cc52013-02-08 11:14:52 -08006673 }
6674 }
6675 else
6676 {
6677 hddLog(VOS_TRACE_LEVEL_FATAL,
6678 "%s: Invalid device mode failed to set valid channel", __func__);
6679 return -EINVAL;
6680 }
6681 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306682 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006683}
6684
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306685static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
6686 struct net_device *dev,
6687 struct ieee80211_channel *chan,
6688 enum nl80211_channel_type channel_type
6689 )
6690{
6691 int ret;
6692
6693 vos_ssr_protect(__func__);
6694 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
6695 vos_ssr_unprotect(__func__);
6696
6697 return ret;
6698}
6699
Jeff Johnson295189b2012-06-20 16:38:30 -07006700#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6701static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6702 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006703#else
6704static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6705 struct cfg80211_beacon_data *params,
6706 const u8 *ssid, size_t ssid_len,
6707 enum nl80211_hidden_ssid hidden_ssid)
6708#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006709{
6710 tsap_Config_t *pConfig;
6711 beacon_data_t *pBeacon = NULL;
6712 struct ieee80211_mgmt *pMgmt_frame;
6713 v_U8_t *pIe=NULL;
6714 v_U16_t capab_info;
6715 eCsrAuthType RSNAuthType;
6716 eCsrEncryptionType RSNEncryptType;
6717 eCsrEncryptionType mcRSNEncryptType;
6718 int status = VOS_STATUS_SUCCESS;
6719 tpWLAN_SAPEventCB pSapEventCallback;
6720 hdd_hostapd_state_t *pHostapdState;
6721 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
6722 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306723 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006724 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306725 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07006726 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08006727 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05306728 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07006729 v_BOOL_t MFPCapable = VOS_FALSE;
6730 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05306731 v_BOOL_t sapEnable11AC =
6732 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07006733 ENTER();
6734
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306735 iniConfig = pHddCtx->cfg_ini;
6736
Jeff Johnson295189b2012-06-20 16:38:30 -07006737 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
6738
6739 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6740
6741 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6742
6743 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6744
6745 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
6746
6747 //channel is already set in the set_channel Call back
6748 //pConfig->channel = pCommitConfig->channel;
6749
6750 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306751 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07006752 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
6753
6754 pConfig->dtim_period = pBeacon->dtim_period;
6755
Arif Hussain6d2a3322013-11-17 19:50:10 -08006756 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07006757 pConfig->dtim_period);
6758
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08006759 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07006760 {
6761 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006762 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05306763 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
6764 {
6765 tANI_BOOLEAN restartNeeded;
6766 pConfig->ieee80211d = 1;
6767 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
6768 sme_setRegInfo(hHal, pConfig->countryCode);
6769 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
6770 }
6771 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006772 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07006773 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07006774 pConfig->ieee80211d = 1;
6775 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
6776 sme_setRegInfo(hHal, pConfig->countryCode);
6777 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07006778 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006779 else
6780 {
6781 pConfig->ieee80211d = 0;
6782 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306783 /*
6784 * If auto channel is configured i.e. channel is 0,
6785 * so skip channel validation.
6786 */
6787 if( AUTO_CHANNEL_SELECT != pConfig->channel )
6788 {
6789 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
6790 {
6791 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006792 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306793 return -EINVAL;
6794 }
6795 }
6796 else
6797 {
6798 if(1 != pHddCtx->is_dynamic_channel_range_set)
6799 {
6800 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
6801 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
6802 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
6803 }
6804 pHddCtx->is_dynamic_channel_range_set = 0;
6805 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006806 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006807 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006808 {
6809 pConfig->ieee80211d = 0;
6810 }
6811 pConfig->authType = eSAP_AUTO_SWITCH;
6812
6813 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306814
6815 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07006816 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
6817
6818 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
6819
6820 /*Set wps station to configured*/
6821 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
6822
6823 if(pIe)
6824 {
6825 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
6826 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006827 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07006828 return -EINVAL;
6829 }
6830 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
6831 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006832 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07006833 /* Check 15 bit of WPS IE as it contain information for wps state
6834 * WPS state
6835 */
6836 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
6837 {
6838 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
6839 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
6840 {
6841 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
6842 }
6843 }
6844 }
6845 else
6846 {
6847 pConfig->wps_state = SAP_WPS_DISABLED;
6848 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306849 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07006850
c_hpothufe599e92014-06-16 11:38:55 +05306851 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6852 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6853 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
6854 eCSR_ENCRYPT_TYPE_NONE;
6855
Jeff Johnson295189b2012-06-20 16:38:30 -07006856 pConfig->RSNWPAReqIELength = 0;
6857 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306858 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006859 WLAN_EID_RSN);
6860 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306861 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006862 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6863 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6864 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306865 /* The actual processing may eventually be more extensive than
6866 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07006867 * by the app.
6868 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306869 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006870 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6871 &RSNEncryptType,
6872 &mcRSNEncryptType,
6873 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006874 &MFPCapable,
6875 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006876 pConfig->pRSNWPAReqIE[1]+2,
6877 pConfig->pRSNWPAReqIE );
6878
6879 if( VOS_STATUS_SUCCESS == status )
6880 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306881 /* Now copy over all the security attributes you have
6882 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006883 * */
6884 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6885 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6886 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6887 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306888 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006889 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006890 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6891 }
6892 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306893
Jeff Johnson295189b2012-06-20 16:38:30 -07006894 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6895 pBeacon->tail, pBeacon->tail_len);
6896
6897 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
6898 {
6899 if (pConfig->pRSNWPAReqIE)
6900 {
6901 /*Mixed mode WPA/WPA2*/
6902 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
6903 pConfig->RSNWPAReqIELength += pIe[1] + 2;
6904 }
6905 else
6906 {
6907 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6908 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6909 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306910 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006911 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6912 &RSNEncryptType,
6913 &mcRSNEncryptType,
6914 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006915 &MFPCapable,
6916 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006917 pConfig->pRSNWPAReqIE[1]+2,
6918 pConfig->pRSNWPAReqIE );
6919
6920 if( VOS_STATUS_SUCCESS == status )
6921 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306922 /* Now copy over all the security attributes you have
6923 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006924 * */
6925 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6926 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6927 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6928 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306929 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006930 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006931 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6932 }
6933 }
6934 }
6935
Jeff Johnson4416a782013-03-25 14:17:50 -07006936 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
6937 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
6938 return -EINVAL;
6939 }
6940
Jeff Johnson295189b2012-06-20 16:38:30 -07006941 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
6942
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006943#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006944 if (params->ssid != NULL)
6945 {
6946 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
6947 pConfig->SSIDinfo.ssid.length = params->ssid_len;
6948 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6949 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6950 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006951#else
6952 if (ssid != NULL)
6953 {
6954 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
6955 pConfig->SSIDinfo.ssid.length = ssid_len;
6956 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6957 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6958 }
6959#endif
6960
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306961 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07006962 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306963
Jeff Johnson295189b2012-06-20 16:38:30 -07006964 /* default value */
6965 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
6966 pConfig->num_accept_mac = 0;
6967 pConfig->num_deny_mac = 0;
6968
6969 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6970 pBeacon->tail, pBeacon->tail_len);
6971
6972 /* pIe for black list is following form:
6973 type : 1 byte
6974 length : 1 byte
6975 OUI : 4 bytes
6976 acl type : 1 byte
6977 no of mac addr in black list: 1 byte
6978 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306979 */
6980 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006981 {
6982 pConfig->SapMacaddr_acl = pIe[6];
6983 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006984 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006985 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306986 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
6987 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006988 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6989 for (i = 0; i < pConfig->num_deny_mac; i++)
6990 {
6991 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6992 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306993 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006994 }
6995 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6996 pBeacon->tail, pBeacon->tail_len);
6997
6998 /* pIe for white list is following form:
6999 type : 1 byte
7000 length : 1 byte
7001 OUI : 4 bytes
7002 acl type : 1 byte
7003 no of mac addr in white list: 1 byte
7004 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307005 */
7006 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007007 {
7008 pConfig->SapMacaddr_acl = pIe[6];
7009 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007010 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007011 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307012 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7013 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007014 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7015 for (i = 0; i < pConfig->num_accept_mac; i++)
7016 {
7017 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7018 acl_entry++;
7019 }
7020 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307021
Jeff Johnson295189b2012-06-20 16:38:30 -07007022 wlan_hdd_set_sapHwmode(pHostapdAdapter);
7023
Jeff Johnsone7245742012-09-05 17:12:55 -07007024#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007025 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307026 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
7027 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05307028 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
7029 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007030 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
7031 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307032 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
7033 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07007034 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307035 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07007036 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307037 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007038
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307039 /* If ACS disable and selected channel <= 14
7040 * OR
7041 * ACS enabled and ACS operating band is choosen as 2.4
7042 * AND
7043 * VHT in 2.4G Disabled
7044 * THEN
7045 * Fallback to 11N mode
7046 */
7047 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
7048 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05307049 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307050 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007051 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307052 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
7053 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007054 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
7055 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007056 }
7057#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307058
Jeff Johnson295189b2012-06-20 16:38:30 -07007059 // ht_capab is not what the name conveys,this is used for protection bitmap
7060 pConfig->ht_capab =
7061 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
7062
7063 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
7064 {
7065 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7066 return -EINVAL;
7067 }
7068
7069 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307070 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07007071 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
7072 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307073 pConfig->obssProtEnabled =
7074 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07007075
Chet Lanctot8cecea22014-02-11 19:09:36 -08007076#ifdef WLAN_FEATURE_11W
7077 pConfig->mfpCapable = MFPCapable;
7078 pConfig->mfpRequired = MFPRequired;
7079 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
7080 pConfig->mfpCapable, pConfig->mfpRequired);
7081#endif
7082
Arif Hussain6d2a3322013-11-17 19:50:10 -08007083 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07007084 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007085 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
7086 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7087 (int)pConfig->channel);
7088 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
7089 pConfig->SapHw_mode, pConfig->privacy,
7090 pConfig->authType);
7091 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
7092 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7093 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7094 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07007095
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307096 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007097 {
7098 //Bss already started. just return.
7099 //TODO Probably it should update some beacon params.
7100 hddLog( LOGE, "Bss Already started...Ignore the request");
7101 EXIT();
7102 return 0;
7103 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307104
Agarwal Ashish51325b52014-06-16 16:50:49 +05307105 if (vos_max_concurrent_connections_reached()) {
7106 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7107 return -EINVAL;
7108 }
7109
Jeff Johnson295189b2012-06-20 16:38:30 -07007110 pConfig->persona = pHostapdAdapter->device_mode;
7111
Peng Xu2446a892014-09-05 17:21:18 +05307112 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
7113 if ( NULL != psmeConfig)
7114 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307115 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05307116 sme_GetConfigParam(hHal, psmeConfig);
7117 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307118#ifdef WLAN_FEATURE_AP_HT40_24G
7119 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7120 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
7121 && pHddCtx->cfg_ini->apHT40_24GEnabled)
7122 {
7123 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
7124 sme_UpdateConfig (hHal, psmeConfig);
7125 }
7126#endif
Peng Xu2446a892014-09-05 17:21:18 +05307127 vos_mem_free(psmeConfig);
7128 }
Peng Xuafc34e32014-09-25 13:23:55 +05307129 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05307130
Jeff Johnson295189b2012-06-20 16:38:30 -07007131 pSapEventCallback = hdd_hostapd_SAPEventCB;
7132 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
7133 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
7134 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007135 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007136 return -EINVAL;
7137 }
7138
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307139 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07007140 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7141
7142 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307143
Jeff Johnson295189b2012-06-20 16:38:30 -07007144 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307145 {
7146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007147 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07007148 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07007149 VOS_ASSERT(0);
7150 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307151
Jeff Johnson295189b2012-06-20 16:38:30 -07007152 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05307153 /* Initialize WMM configuation */
7154 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307155 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007156
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007157#ifdef WLAN_FEATURE_P2P_DEBUG
7158 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
7159 {
7160 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
7161 {
7162 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7163 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007164 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007165 }
7166 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
7167 {
7168 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7169 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007170 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007171 }
7172 }
7173#endif
7174
Jeff Johnson295189b2012-06-20 16:38:30 -07007175 pHostapdState->bCommit = TRUE;
7176 EXIT();
7177
7178 return 0;
7179}
7180
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007181#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307182static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307183 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007184 struct beacon_parameters *params)
7185{
7186 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307187 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307188 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007189
7190 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307191
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307192 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7193 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
7194 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307195 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
7196 hdd_device_modetoString(pAdapter->device_mode),
7197 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007198
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307199 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7200 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307201 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007202 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307203 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007204 }
7205
Agarwal Ashish51325b52014-06-16 16:50:49 +05307206 if (vos_max_concurrent_connections_reached()) {
7207 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7208 return -EINVAL;
7209 }
7210
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307211 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007212 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007213 )
7214 {
7215 beacon_data_t *old,*new;
7216
7217 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307218
Jeff Johnson295189b2012-06-20 16:38:30 -07007219 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307220 {
7221 hddLog(VOS_TRACE_LEVEL_WARN,
7222 FL("already beacon info added to session(%d)"),
7223 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007224 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307225 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007226
7227 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7228
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307229 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07007230 {
7231 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007232 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007233 return -EINVAL;
7234 }
7235
7236 pAdapter->sessionCtx.ap.beacon = new;
7237
7238 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7239 }
7240
7241 EXIT();
7242 return status;
7243}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307244
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307245static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
7246 struct net_device *dev,
7247 struct beacon_parameters *params)
7248{
7249 int ret;
7250
7251 vos_ssr_protect(__func__);
7252 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
7253 vos_ssr_unprotect(__func__);
7254
7255 return ret;
7256}
7257
7258static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007259 struct net_device *dev,
7260 struct beacon_parameters *params)
7261{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307262 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307263 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7264 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307265 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007266
7267 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307268
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307269 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7270 TRACE_CODE_HDD_CFG80211_SET_BEACON,
7271 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
7272 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7273 __func__, hdd_device_modetoString(pAdapter->device_mode),
7274 pAdapter->device_mode);
7275
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307276 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7277 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307278 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007279 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307280 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007281 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307282
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307283 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007284 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307285 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007286 {
7287 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307288
Jeff Johnson295189b2012-06-20 16:38:30 -07007289 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307290
Jeff Johnson295189b2012-06-20 16:38:30 -07007291 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307292 {
7293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7294 FL("session(%d) old and new heads points to NULL"),
7295 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007296 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307297 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007298
7299 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7300
7301 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307302 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007303 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007304 return -EINVAL;
7305 }
7306
7307 pAdapter->sessionCtx.ap.beacon = new;
7308
7309 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7310 }
7311
7312 EXIT();
7313 return status;
7314}
7315
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307316static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
7317 struct net_device *dev,
7318 struct beacon_parameters *params)
7319{
7320 int ret;
7321
7322 vos_ssr_protect(__func__);
7323 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
7324 vos_ssr_unprotect(__func__);
7325
7326 return ret;
7327}
7328
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007329#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7330
7331#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307332static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007333 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007334#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307335static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007336 struct net_device *dev)
7337#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007338{
7339 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07007340 hdd_context_t *pHddCtx = NULL;
7341 hdd_scaninfo_t *pScanInfo = NULL;
7342 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307343 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307344 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007345
7346 ENTER();
7347
7348 if (NULL == pAdapter)
7349 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007351 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007352 return -ENODEV;
7353 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007354
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307355 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7356 TRACE_CODE_HDD_CFG80211_STOP_AP,
7357 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307358 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7359 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307360 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007361 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307362 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07007363 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007364
7365 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
7366 if (NULL == staAdapter)
7367 {
7368 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
7369 if (NULL == staAdapter)
7370 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07007371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7372 "%s: HDD adapter context for STA/P2P-CLI is Null",
7373 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007374 }
7375 }
7376
7377 pScanInfo = &pHddCtx->scan_info;
7378
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307379 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7380 __func__, hdd_device_modetoString(pAdapter->device_mode),
7381 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007382
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307383 ret = wlan_hdd_scan_abort(pAdapter);
7384
Girish Gowli4bf7a632014-06-12 13:42:11 +05307385 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07007386 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7388 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307389
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307390 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07007391 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7393 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08007394
Jeff Johnsone7245742012-09-05 17:12:55 -07007395 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307396 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07007397 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307398 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07007399 }
7400
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05307401 /* Delete all associated STAs before stopping AP/P2P GO */
7402 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05307403 hdd_hostapd_stop(dev);
7404
Jeff Johnson295189b2012-06-20 16:38:30 -07007405 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007406 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007407 )
7408 {
7409 beacon_data_t *old;
7410
7411 old = pAdapter->sessionCtx.ap.beacon;
7412
7413 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307414 {
7415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7416 FL("session(%d) beacon data points to NULL"),
7417 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007418 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307419 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007420
Jeff Johnson295189b2012-06-20 16:38:30 -07007421 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007422
7423 mutex_lock(&pHddCtx->sap_lock);
7424 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7425 {
Jeff Johnson4416a782013-03-25 14:17:50 -07007426 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007427 {
7428 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7429
7430 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7431
7432 if (!VOS_IS_STATUS_SUCCESS(status))
7433 {
7434 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007435 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007436 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307437 }
7438 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007439 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307440 /* BSS stopped, clear the active sessions for this device mode */
7441 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007442 }
7443 mutex_unlock(&pHddCtx->sap_lock);
7444
7445 if(status != VOS_STATUS_SUCCESS)
7446 {
7447 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007448 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007449 return -EINVAL;
7450 }
7451
Jeff Johnson4416a782013-03-25 14:17:50 -07007452 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007453 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
7454 ==eHAL_STATUS_FAILURE)
7455 {
7456 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007457 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007458 }
7459
Jeff Johnson4416a782013-03-25 14:17:50 -07007460 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007461 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7462 eANI_BOOLEAN_FALSE) )
7463 {
7464 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007465 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007466 }
7467
7468 // Reset WNI_CFG_PROBE_RSP Flags
7469 wlan_hdd_reset_prob_rspies(pAdapter);
7470
7471 pAdapter->sessionCtx.ap.beacon = NULL;
7472 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007473#ifdef WLAN_FEATURE_P2P_DEBUG
7474 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7475 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7476 {
7477 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7478 "GO got removed");
7479 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7480 }
7481#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007482 }
7483 EXIT();
7484 return status;
7485}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007486
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307487#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7488static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7489 struct net_device *dev)
7490{
7491 int ret;
7492
7493 vos_ssr_protect(__func__);
7494 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7495 vos_ssr_unprotect(__func__);
7496
7497 return ret;
7498}
7499#else
7500static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7501 struct net_device *dev)
7502{
7503 int ret;
7504
7505 vos_ssr_protect(__func__);
7506 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7507 vos_ssr_unprotect(__func__);
7508
7509 return ret;
7510}
7511#endif
7512
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007513#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7514
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307515static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307516 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007517 struct cfg80211_ap_settings *params)
7518{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307519 hdd_adapter_t *pAdapter;
7520 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307521 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007522
7523 ENTER();
7524
Girish Gowlib143d7a2015-02-18 19:39:55 +05307525 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007526 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05307528 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307529 return -ENODEV;
7530 }
7531
7532 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7533 if (NULL == pAdapter)
7534 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307536 "%s: HDD adapter is Null", __func__);
7537 return -ENODEV;
7538 }
7539
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307540 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7541 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
7542 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307543 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7544 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307546 "%s: HDD adapter magic is invalid", __func__);
7547 return -ENODEV;
7548 }
7549
7550 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307551 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307552 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307553 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307554 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307555 }
7556
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307557 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7558 __func__, hdd_device_modetoString(pAdapter->device_mode),
7559 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307560
7561 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007562 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007563 )
7564 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307565 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007566
7567 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307568
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007569 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307570 {
7571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7572 FL("already beacon info added to session(%d)"),
7573 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007574 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307575 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007576
Girish Gowlib143d7a2015-02-18 19:39:55 +05307577#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7578 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7579 &new,
7580 &params->beacon);
7581#else
7582 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7583 &new,
7584 &params->beacon,
7585 params->dtim_period);
7586#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007587
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307588 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007589 {
7590 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307591 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007592 return -EINVAL;
7593 }
7594 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007595#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007596 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7597#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7598 params->channel, params->channel_type);
7599#else
7600 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7601#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007602#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007603 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
7604 params->ssid_len, params->hidden_ssid);
7605 }
7606
7607 EXIT();
7608 return status;
7609}
7610
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307611static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7612 struct net_device *dev,
7613 struct cfg80211_ap_settings *params)
7614{
7615 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007616
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307617 vos_ssr_protect(__func__);
7618 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
7619 vos_ssr_unprotect(__func__);
7620
7621 return ret;
7622}
7623
7624static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007625 struct net_device *dev,
7626 struct cfg80211_beacon_data *params)
7627{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307628 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307629 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307630 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007631
7632 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307633
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307634 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7635 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7636 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007637 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007638 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307639
7640 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7641 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307642 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007643 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307644 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007645 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007646
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307647 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007648 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307649 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007650 {
7651 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307652
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007653 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307654
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007655 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307656 {
7657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7658 FL("session(%d) beacon data points to NULL"),
7659 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007660 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307661 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007662
7663 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
7664
7665 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307666 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007667 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007668 return -EINVAL;
7669 }
7670
7671 pAdapter->sessionCtx.ap.beacon = new;
7672
7673 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
7674 }
7675
7676 EXIT();
7677 return status;
7678}
7679
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307680static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
7681 struct net_device *dev,
7682 struct cfg80211_beacon_data *params)
7683{
7684 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007685
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307686 vos_ssr_protect(__func__);
7687 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
7688 vos_ssr_unprotect(__func__);
7689
7690 return ret;
7691}
7692
7693#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007694
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307695static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007696 struct net_device *dev,
7697 struct bss_parameters *params)
7698{
7699 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307700 hdd_context_t *pHddCtx;
7701 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007702
7703 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307704
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307705 if (NULL == pAdapter)
7706 {
7707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7708 "%s: HDD adapter is Null", __func__);
7709 return -ENODEV;
7710 }
7711 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307712 ret = wlan_hdd_validate_context(pHddCtx);
7713 if (0 != ret)
7714 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307715 return ret;
7716 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307717 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7718 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
7719 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307720 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7721 __func__, hdd_device_modetoString(pAdapter->device_mode),
7722 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007723
7724 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007725 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307726 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007727 {
7728 /* ap_isolate == -1 means that in change bss, upper layer doesn't
7729 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307730 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07007731 {
7732 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307733 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007734 }
7735
7736 EXIT();
7737 return 0;
7738}
7739
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307740static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
7741 struct net_device *dev,
7742 struct bss_parameters *params)
7743{
7744 int ret;
7745
7746 vos_ssr_protect(__func__);
7747 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
7748 vos_ssr_unprotect(__func__);
7749
7750 return ret;
7751}
Kiet Lam10841362013-11-01 11:36:50 +05307752/* FUNCTION: wlan_hdd_change_country_code_cd
7753* to wait for contry code completion
7754*/
7755void* wlan_hdd_change_country_code_cb(void *pAdapter)
7756{
7757 hdd_adapter_t *call_back_pAdapter = pAdapter;
7758 complete(&call_back_pAdapter->change_country_code);
7759 return NULL;
7760}
7761
Jeff Johnson295189b2012-06-20 16:38:30 -07007762/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307763 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07007764 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
7765 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307766int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007767 struct net_device *ndev,
7768 enum nl80211_iftype type,
7769 u32 *flags,
7770 struct vif_params *params
7771 )
7772{
7773 struct wireless_dev *wdev;
7774 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007775 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07007776 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007777 tCsrRoamProfile *pRoamProfile = NULL;
7778 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307779 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007780 eMib_dot11DesiredBssType connectedBssType;
7781 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307782 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007783
7784 ENTER();
7785
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307786 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007787 {
7788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7789 "%s: Adapter context is null", __func__);
7790 return VOS_STATUS_E_FAILURE;
7791 }
7792
7793 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7794 if (!pHddCtx)
7795 {
7796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7797 "%s: HDD context is null", __func__);
7798 return VOS_STATUS_E_FAILURE;
7799 }
7800
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307801 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7802 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
7803 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307804 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307805 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007806 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307807 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007808 }
7809
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307810 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7811 __func__, hdd_device_modetoString(pAdapter->device_mode),
7812 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007813
Agarwal Ashish51325b52014-06-16 16:50:49 +05307814 if (vos_max_concurrent_connections_reached()) {
7815 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7816 return -EINVAL;
7817 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307818 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007819 wdev = ndev->ieee80211_ptr;
7820
7821#ifdef WLAN_BTAMP_FEATURE
7822 if((NL80211_IFTYPE_P2P_CLIENT == type)||
7823 (NL80211_IFTYPE_ADHOC == type)||
7824 (NL80211_IFTYPE_AP == type)||
7825 (NL80211_IFTYPE_P2P_GO == type))
7826 {
7827 pHddCtx->isAmpAllowed = VOS_FALSE;
7828 // stop AMP traffic
7829 status = WLANBAP_StopAmp();
7830 if(VOS_STATUS_SUCCESS != status )
7831 {
7832 pHddCtx->isAmpAllowed = VOS_TRUE;
7833 hddLog(VOS_TRACE_LEVEL_FATAL,
7834 "%s: Failed to stop AMP", __func__);
7835 return -EINVAL;
7836 }
7837 }
7838#endif //WLAN_BTAMP_FEATURE
7839 /* Reset the current device mode bit mask*/
7840 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7841
7842 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007843 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07007844 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07007845 )
7846 {
7847 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007848 if (!pWextState)
7849 {
7850 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7851 "%s: pWextState is null", __func__);
7852 return VOS_STATUS_E_FAILURE;
7853 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007854 pRoamProfile = &pWextState->roamProfile;
7855 LastBSSType = pRoamProfile->BSSType;
7856
7857 switch (type)
7858 {
7859 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007860 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007861 hddLog(VOS_TRACE_LEVEL_INFO,
7862 "%s: setting interface Type to INFRASTRUCTURE", __func__);
7863 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07007864#ifdef WLAN_FEATURE_11AC
7865 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
7866 {
7867 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
7868 }
7869#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307870 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07007871 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007872 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007873 //Check for sub-string p2p to confirm its a p2p interface
7874 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307875 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007876 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7877 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7878 }
7879 else
7880 {
7881 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007882 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007883 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007884 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05307885
Jeff Johnson295189b2012-06-20 16:38:30 -07007886 case NL80211_IFTYPE_ADHOC:
7887 hddLog(VOS_TRACE_LEVEL_INFO,
7888 "%s: setting interface Type to ADHOC", __func__);
7889 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
7890 pRoamProfile->phyMode =
7891 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07007892 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007893 wdev->iftype = type;
7894 break;
7895
7896 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007897 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007898 {
7899 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7900 "%s: setting interface Type to %s", __func__,
7901 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
7902
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007903 //Cancel any remain on channel for GO mode
7904 if (NL80211_IFTYPE_P2P_GO == type)
7905 {
7906 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
7907 }
Mohit Khanna0f232092012-09-11 14:46:08 -07007908 if (NL80211_IFTYPE_AP == type)
7909 {
7910 /* As Loading WLAN Driver one interface being created for p2p device
7911 * address. This will take one HW STA and the max number of clients
7912 * that can connect to softAP will be reduced by one. so while changing
7913 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
7914 * interface as it is not required in SoftAP mode.
7915 */
7916
7917 // Get P2P Adapter
7918 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
7919
7920 if (pP2pAdapter)
7921 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307922 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05307923 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07007924 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
7925 }
7926 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05307927 //Disable IMPS & BMPS for SAP/GO
7928 if(VOS_STATUS_E_FAILURE ==
7929 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
7930 {
7931 //Fail to Exit BMPS
7932 VOS_ASSERT(0);
7933 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05307934
7935 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
7936
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307937#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07007938
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307939 /* A Mutex Lock is introduced while changing the mode to
7940 * protect the concurrent access for the Adapters by TDLS
7941 * module.
7942 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307943 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307944#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007945 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05307946 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07007947 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07007948 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7949 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307950#ifdef FEATURE_WLAN_TDLS
7951 mutex_unlock(&pHddCtx->tdls_lock);
7952#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007953 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
7954 (pConfig->apRandomBssidEnabled))
7955 {
7956 /* To meet Android requirements create a randomized
7957 MAC address of the form 02:1A:11:Fx:xx:xx */
7958 get_random_bytes(&ndev->dev_addr[3], 3);
7959 ndev->dev_addr[0] = 0x02;
7960 ndev->dev_addr[1] = 0x1A;
7961 ndev->dev_addr[2] = 0x11;
7962 ndev->dev_addr[3] |= 0xF0;
7963 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
7964 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08007965 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
7966 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007967 }
7968
Jeff Johnson295189b2012-06-20 16:38:30 -07007969 hdd_set_ap_ops( pAdapter->dev );
7970
Kiet Lam10841362013-11-01 11:36:50 +05307971 /* This is for only SAP mode where users can
7972 * control country through ini.
7973 * P2P GO follows station country code
7974 * acquired during the STA scanning. */
7975 if((NL80211_IFTYPE_AP == type) &&
7976 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
7977 {
7978 int status = 0;
7979 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
7980 "%s: setting country code from INI ", __func__);
7981 init_completion(&pAdapter->change_country_code);
7982 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
7983 (void *)(tSmeChangeCountryCallback)
7984 wlan_hdd_change_country_code_cb,
7985 pConfig->apCntryCode, pAdapter,
7986 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05307987 eSIR_FALSE,
7988 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05307989 if (eHAL_STATUS_SUCCESS == status)
7990 {
7991 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307992 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05307993 &pAdapter->change_country_code,
7994 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307995 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05307996 {
7997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307998 FL("SME Timed out while setting country code %ld"),
7999 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08008000
8001 if (pHddCtx->isLogpInProgress)
8002 {
8003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8004 "%s: LOGP in Progress. Ignore!!!", __func__);
8005 return -EAGAIN;
8006 }
Kiet Lam10841362013-11-01 11:36:50 +05308007 }
8008 }
8009 else
8010 {
8011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008012 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05308013 return -EINVAL;
8014 }
8015 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008016 status = hdd_init_ap_mode(pAdapter);
8017 if(status != VOS_STATUS_SUCCESS)
8018 {
8019 hddLog(VOS_TRACE_LEVEL_FATAL,
8020 "%s: Error initializing the ap mode", __func__);
8021 return -EINVAL;
8022 }
8023 hdd_set_conparam(1);
8024
Jeff Johnson295189b2012-06-20 16:38:30 -07008025 /*interface type changed update in wiphy structure*/
8026 if(wdev)
8027 {
8028 wdev->iftype = type;
8029 pHddCtx->change_iface = type;
8030 }
8031 else
8032 {
8033 hddLog(VOS_TRACE_LEVEL_ERROR,
8034 "%s: ERROR !!!! Wireless dev is NULL", __func__);
8035 return -EINVAL;
8036 }
8037 goto done;
8038 }
8039
8040 default:
8041 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8042 __func__);
8043 return -EOPNOTSUPP;
8044 }
8045 }
8046 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008047 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008048 )
8049 {
8050 switch(type)
8051 {
8052 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008053 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008054 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05308055
8056 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308057#ifdef FEATURE_WLAN_TDLS
8058
8059 /* A Mutex Lock is introduced while changing the mode to
8060 * protect the concurrent access for the Adapters by TDLS
8061 * module.
8062 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308063 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308064#endif
c_hpothu002231a2015-02-05 14:58:51 +05308065 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008066 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008067 //Check for sub-string p2p to confirm its a p2p interface
8068 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008069 {
8070 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8071 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8072 }
8073 else
8074 {
8075 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008076 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008077 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008078 hdd_set_conparam(0);
8079 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008080 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
8081 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308082#ifdef FEATURE_WLAN_TDLS
8083 mutex_unlock(&pHddCtx->tdls_lock);
8084#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308085 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008086 if( VOS_STATUS_SUCCESS != status )
8087 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07008088 /* In case of JB, for P2P-GO, only change interface will be called,
8089 * This is the right place to enable back bmps_imps()
8090 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308091 if (pHddCtx->hdd_wlan_suspended)
8092 {
8093 hdd_set_pwrparams(pHddCtx);
8094 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008095 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008096 goto done;
8097 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008098 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008099 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008100 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8101 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008102 goto done;
8103 default:
8104 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8105 __func__);
8106 return -EOPNOTSUPP;
8107
8108 }
8109
8110 }
8111 else
8112 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308113 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
8114 __func__, hdd_device_modetoString(pAdapter->device_mode),
8115 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008116 return -EOPNOTSUPP;
8117 }
8118
8119
8120 if(pRoamProfile)
8121 {
8122 if ( LastBSSType != pRoamProfile->BSSType )
8123 {
8124 /*interface type changed update in wiphy structure*/
8125 wdev->iftype = type;
8126
8127 /*the BSS mode changed, We need to issue disconnect
8128 if connected or in IBSS disconnect state*/
8129 if ( hdd_connGetConnectedBssType(
8130 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
8131 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
8132 {
8133 /*need to issue a disconnect to CSR.*/
8134 INIT_COMPLETION(pAdapter->disconnect_comp_var);
8135 if( eHAL_STATUS_SUCCESS ==
8136 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
8137 pAdapter->sessionId,
8138 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
8139 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308140 ret = wait_for_completion_interruptible_timeout(
8141 &pAdapter->disconnect_comp_var,
8142 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
8143 if (ret <= 0)
8144 {
8145 hddLog(VOS_TRACE_LEVEL_ERROR,
8146 FL("wait on disconnect_comp_var failed %ld"), ret);
8147 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008148 }
8149 }
8150 }
8151 }
8152
8153done:
8154 /*set bitmask based on updated value*/
8155 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07008156
8157 /* Only STA mode support TM now
8158 * all other mode, TM feature should be disabled */
8159 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
8160 (~VOS_STA & pHddCtx->concurrency_mode) )
8161 {
8162 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
8163 }
8164
Jeff Johnson295189b2012-06-20 16:38:30 -07008165#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308166 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05308167 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07008168 {
8169 //we are ok to do AMP
8170 pHddCtx->isAmpAllowed = VOS_TRUE;
8171 }
8172#endif //WLAN_BTAMP_FEATURE
8173 EXIT();
8174 return 0;
8175}
8176
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308177/*
8178 * FUNCTION: wlan_hdd_cfg80211_change_iface
8179 * wrapper function to protect the actual implementation from SSR.
8180 */
8181int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
8182 struct net_device *ndev,
8183 enum nl80211_iftype type,
8184 u32 *flags,
8185 struct vif_params *params
8186 )
8187{
8188 int ret;
8189
8190 vos_ssr_protect(__func__);
8191 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
8192 vos_ssr_unprotect(__func__);
8193
8194 return ret;
8195}
8196
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008197#ifdef FEATURE_WLAN_TDLS
8198static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
8199 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
8200{
8201 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8202 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8203 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008204 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308205 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308206 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008207
8208 ENTER();
8209
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308210 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008211 {
8212 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8213 "Invalid arguments");
8214 return -EINVAL;
8215 }
Hoonki Lee27511902013-03-14 18:19:06 -07008216
8217 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
8218 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
8219 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07008221 "%s: TDLS mode is disabled OR not enabled in FW."
8222 MAC_ADDRESS_STR " Request declined.",
8223 __func__, MAC_ADDR_ARRAY(mac));
8224 return -ENOTSUPP;
8225 }
8226
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008227 if (pHddCtx->isLogpInProgress)
8228 {
8229 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8230 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05308231 wlan_hdd_tdls_set_link_status(pAdapter,
8232 mac,
8233 eTDLS_LINK_IDLE,
8234 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008235 return -EBUSY;
8236 }
8237
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05308238 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008239
8240 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308241 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008242 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
8243 __func__, MAC_ADDR_ARRAY(mac), update);
8244 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008245 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008246
8247 /* in add station, we accept existing valid staId if there is */
8248 if ((0 == update) &&
8249 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
8250 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008251 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008253 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008254 " link_status %d. staId %d. add station ignored.",
8255 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
8256 return 0;
8257 }
8258 /* in change station, we accept only when staId is valid */
8259 if ((1 == update) &&
8260 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
8261 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
8262 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308263 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008264 "%s: " MAC_ADDRESS_STR
8265 " link status %d. staId %d. change station %s.",
8266 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
8267 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
8268 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008269 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008270
8271 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308272 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008273 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8275 "%s: " MAC_ADDRESS_STR
8276 " TDLS setup is ongoing. Request declined.",
8277 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07008278 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008279 }
8280
8281 /* first to check if we reached to maximum supported TDLS peer.
8282 TODO: for now, return -EPERM looks working fine,
8283 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308284 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8285 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008286 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8288 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308289 " TDLS Max peer already connected. Request declined."
8290 " Num of peers (%d), Max allowed (%d).",
8291 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
8292 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008293 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008294 }
8295 else
8296 {
8297 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308298 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008299 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008300 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8302 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
8303 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008304 return -EPERM;
8305 }
8306 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008307 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05308308 wlan_hdd_tdls_set_link_status(pAdapter,
8309 mac,
8310 eTDLS_LINK_CONNECTING,
8311 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008312
Jeff Johnsond75fe012013-04-06 10:53:06 -07008313 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308314 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008315 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308316 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008317 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008318 if(StaParams->htcap_present)
8319 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008321 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008323 "ht_capa->extended_capabilities: %0x",
8324 StaParams->HTCap.extendedHtCapInfo);
8325 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008327 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008329 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008330 if(StaParams->vhtcap_present)
8331 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008333 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
8334 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
8335 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
8336 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008337 {
8338 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008340 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008342 "[%d]: %x ", i, StaParams->supported_rates[i]);
8343 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07008344 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308345 else if ((1 == update) && (NULL == StaParams))
8346 {
8347 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8348 "%s : update is true, but staParams is NULL. Error!", __func__);
8349 return -EPERM;
8350 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008351
8352 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
8353
8354 if (!update)
8355 {
8356 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
8357 pAdapter->sessionId, mac);
8358 }
8359 else
8360 {
8361 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
8362 pAdapter->sessionId, mac, StaParams);
8363 }
8364
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308365 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008366 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
8367
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308368 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008369 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308371 "%s: timeout waiting for tdls add station indication %ld",
8372 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008373 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008374 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308375
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008376 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
8377 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008379 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008380 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008381 }
8382
8383 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008384
8385error:
Atul Mittal115287b2014-07-08 13:26:33 +05308386 wlan_hdd_tdls_set_link_status(pAdapter,
8387 mac,
8388 eTDLS_LINK_IDLE,
8389 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008390 return -EPERM;
8391
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008392}
8393#endif
8394
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308395static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008396 struct net_device *dev,
8397 u8 *mac,
8398 struct station_parameters *params)
8399{
8400 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308401 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308402 hdd_context_t *pHddCtx;
8403 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008404 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308405 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008406#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008407 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008408 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308409 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008410#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008411
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308412 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308413
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308414 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308415 if ((NULL == pAdapter))
8416 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308418 "invalid adapter ");
8419 return -EINVAL;
8420 }
8421
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308422 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8423 TRACE_CODE_HDD_CHANGE_STATION,
8424 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05308425 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308426
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308427 ret = wlan_hdd_validate_context(pHddCtx);
8428 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05308429 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308430 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308431 }
8432
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308433 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8434
8435 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008436 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8438 "invalid HDD station context");
8439 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008440 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008441 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
8442
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008443 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8444 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07008445 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008446 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07008447 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308448 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07008449 WLANTL_STA_AUTHENTICATED);
8450
Gopichand Nakkala29149562013-05-10 21:43:41 +05308451 if (status != VOS_STATUS_SUCCESS)
8452 {
8453 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8454 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8455 return -EINVAL;
8456 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008457 }
8458 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008459 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8460 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308461#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008462 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8463 StaParams.capability = params->capability;
8464 StaParams.uapsd_queues = params->uapsd_queues;
8465 StaParams.max_sp = params->max_sp;
8466
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308467 /* Convert (first channel , number of channels) tuple to
8468 * the total list of channels. This goes with the assumption
8469 * that if the first channel is < 14, then the next channels
8470 * are an incremental of 1 else an incremental of 4 till the number
8471 * of channels.
8472 */
8473 if (0 != params->supported_channels_len) {
8474 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8475 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8476 {
8477 int wifi_chan_index;
8478 StaParams.supported_channels[j] = params->supported_channels[i];
8479 wifi_chan_index =
8480 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8481 no_of_channels = params->supported_channels[i+1];
8482 for(k=1; k <= no_of_channels; k++)
8483 {
8484 StaParams.supported_channels[j+1] =
8485 StaParams.supported_channels[j] + wifi_chan_index;
8486 j+=1;
8487 }
8488 }
8489 StaParams.supported_channels_len = j;
8490 }
8491 vos_mem_copy(StaParams.supported_oper_classes,
8492 params->supported_oper_classes,
8493 params->supported_oper_classes_len);
8494 StaParams.supported_oper_classes_len =
8495 params->supported_oper_classes_len;
8496
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008497 if (0 != params->ext_capab_len)
8498 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8499 sizeof(StaParams.extn_capability));
8500
8501 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008502 {
8503 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008504 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008505 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008506
8507 StaParams.supported_rates_len = params->supported_rates_len;
8508
8509 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8510 * The supported_rates array , for all the structures propogating till Add Sta
8511 * to the firmware has to be modified , if the supplicant (ieee80211) is
8512 * modified to send more rates.
8513 */
8514
8515 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8516 */
8517 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8518 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8519
8520 if (0 != StaParams.supported_rates_len) {
8521 int i = 0;
8522 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8523 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008525 "Supported Rates with Length %d", StaParams.supported_rates_len);
8526 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008528 "[%d]: %0x", i, StaParams.supported_rates[i]);
8529 }
8530
8531 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008532 {
8533 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008534 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008535 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008536
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008537 if (0 != params->ext_capab_len ) {
8538 /*Define A Macro : TODO Sunil*/
8539 if ((1<<4) & StaParams.extn_capability[3]) {
8540 isBufSta = 1;
8541 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308542 /* TDLS Channel Switching Support */
8543 if ((1<<6) & StaParams.extn_capability[3]) {
8544 isOffChannelSupported = 1;
8545 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008546 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308547 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8548 &StaParams, isBufSta,
8549 isOffChannelSupported);
8550
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308551 if (VOS_STATUS_SUCCESS != status) {
8552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8553 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8554 return -EINVAL;
8555 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008556 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8557
8558 if (VOS_STATUS_SUCCESS != status) {
8559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8560 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8561 return -EINVAL;
8562 }
8563 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008564#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308565 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008566 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008567 return status;
8568}
8569
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308570static int wlan_hdd_change_station(struct wiphy *wiphy,
8571 struct net_device *dev,
8572 u8 *mac,
8573 struct station_parameters *params)
8574{
8575 int ret;
8576
8577 vos_ssr_protect(__func__);
8578 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
8579 vos_ssr_unprotect(__func__);
8580
8581 return ret;
8582}
8583
Jeff Johnson295189b2012-06-20 16:38:30 -07008584/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308585 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008586 * This function is used to initialize the key information
8587 */
8588#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308589static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008590 struct net_device *ndev,
8591 u8 key_index, bool pairwise,
8592 const u8 *mac_addr,
8593 struct key_params *params
8594 )
8595#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308596static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008597 struct net_device *ndev,
8598 u8 key_index, const u8 *mac_addr,
8599 struct key_params *params
8600 )
8601#endif
8602{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008603 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07008604 tCsrRoamSetKey setKey;
8605 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308606 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008607 v_U32_t roamId= 0xFF;
8608 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008609 hdd_hostapd_state_t *pHostapdState;
8610 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008611 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308612 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008613
8614 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308615
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308616 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8617 TRACE_CODE_HDD_CFG80211_ADD_KEY,
8618 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308619 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8620 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308621 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008622 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308623 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008624 }
8625
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308626 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8627 __func__, hdd_device_modetoString(pAdapter->device_mode),
8628 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008629
8630 if (CSR_MAX_NUM_KEY <= key_index)
8631 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008632 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008633 key_index);
8634
8635 return -EINVAL;
8636 }
8637
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008638 if (CSR_MAX_KEY_LEN < params->key_len)
8639 {
8640 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
8641 params->key_len);
8642
8643 return -EINVAL;
8644 }
8645
8646 hddLog(VOS_TRACE_LEVEL_INFO,
8647 "%s: called with key index = %d & key length %d",
8648 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008649
8650 /*extract key idx, key len and key*/
8651 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8652 setKey.keyId = key_index;
8653 setKey.keyLength = params->key_len;
8654 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
8655
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008656 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07008657 {
8658 case WLAN_CIPHER_SUITE_WEP40:
8659 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
8660 break;
8661
8662 case WLAN_CIPHER_SUITE_WEP104:
8663 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
8664 break;
8665
8666 case WLAN_CIPHER_SUITE_TKIP:
8667 {
8668 u8 *pKey = &setKey.Key[0];
8669 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
8670
8671 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
8672
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008673 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07008674
8675 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008676 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008677 |--------------|----------|----------|
8678 <---16bytes---><--8bytes--><--8bytes-->
8679
8680 */
8681 /*Sme expects the 32 bytes key to be in the below order
8682
8683 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008684 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008685 |--------------|----------|----------|
8686 <---16bytes---><--8bytes--><--8bytes-->
8687 */
8688 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008689 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07008690
8691 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008692 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008693
8694 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008695 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008696
8697
8698 break;
8699 }
8700
8701 case WLAN_CIPHER_SUITE_CCMP:
8702 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
8703 break;
8704
8705#ifdef FEATURE_WLAN_WAPI
8706 case WLAN_CIPHER_SUITE_SMS4:
8707 {
8708 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8709 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
8710 params->key, params->key_len);
8711 return 0;
8712 }
8713#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008714
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008715#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07008716 case WLAN_CIPHER_SUITE_KRK:
8717 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
8718 break;
8719#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008720
8721#ifdef WLAN_FEATURE_11W
8722 case WLAN_CIPHER_SUITE_AES_CMAC:
8723 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07008724 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07008725#endif
8726
Jeff Johnson295189b2012-06-20 16:38:30 -07008727 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008728 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07008729 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308730 status = -EOPNOTSUPP;
8731 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008732 }
8733
8734 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
8735 __func__, setKey.encType);
8736
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008737 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07008738#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8739 (!pairwise)
8740#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008741 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07008742#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008743 )
8744 {
8745 /* set group key*/
8746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8747 "%s- %d: setting Broadcast key",
8748 __func__, __LINE__);
8749 setKey.keyDirection = eSIR_RX_ONLY;
8750 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8751 }
8752 else
8753 {
8754 /* set pairwise key*/
8755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8756 "%s- %d: setting pairwise key",
8757 __func__, __LINE__);
8758 setKey.keyDirection = eSIR_TX_RX;
8759 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8760 }
8761 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
8762 {
8763 setKey.keyDirection = eSIR_TX_RX;
8764 /*Set the group key*/
8765 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8766 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07008767
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008768 if ( 0 != status )
8769 {
8770 hddLog(VOS_TRACE_LEVEL_ERROR,
8771 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308772 status = -EINVAL;
8773 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008774 }
8775 /*Save the keys here and call sme_RoamSetKey for setting
8776 the PTK after peer joins the IBSS network*/
8777 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
8778 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308779 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008780 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05308781 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
8782 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
8783 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008784 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008785 if( pHostapdState->bssState == BSS_START )
8786 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008787 status = WLANSAP_SetKeySta( pVosContext, &setKey);
8788
8789 if ( status != eHAL_STATUS_SUCCESS )
8790 {
8791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8792 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8793 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308794 status = -EINVAL;
8795 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008796 }
8797 }
8798
8799 /* Saving WEP keys */
8800 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
8801 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
8802 {
8803 //Save the wep key in ap context. Issue setkey after the BSS is started.
8804 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8805 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
8806 }
8807 else
8808 {
8809 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008810 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008811 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
8812 }
8813 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008814 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
8815 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008816 {
8817 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8818 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8819
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308820#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8821 if (!pairwise)
8822#else
8823 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8824#endif
8825 {
8826 /* set group key*/
8827 if (pHddStaCtx->roam_info.deferKeyComplete)
8828 {
8829 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8830 "%s- %d: Perform Set key Complete",
8831 __func__, __LINE__);
8832 hdd_PerformRoamSetKeyComplete(pAdapter);
8833 }
8834 }
8835
Jeff Johnson295189b2012-06-20 16:38:30 -07008836 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
8837
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08008838 pWextState->roamProfile.Keys.defaultIndex = key_index;
8839
8840
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008841 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008842 params->key, params->key_len);
8843
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308844
Jeff Johnson295189b2012-06-20 16:38:30 -07008845 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8846
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308847 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008848 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308849 __func__, setKey.peerMac[0], setKey.peerMac[1],
8850 setKey.peerMac[2], setKey.peerMac[3],
8851 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008852 setKey.keyDirection);
8853
Nirav Shah4f765af2015-01-21 19:51:30 +05308854 /* Wait for EAPOL M4 before setting key.
8855 * No need to consider Dynamic WEP as we will receive M8.
8856 */
8857 if ( (setKey.encType == eCSR_ENCRYPT_TYPE_AES ||
8858 setKey.encType == eCSR_ENCRYPT_TYPE_TKIP) &&
8859 ( 1
8860#if defined WLAN_FEATURE_VOWIFI_11R
8861 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN
8862 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN_PSK
8863#endif
8864#ifdef FEATURE_WLAN_ESE
8865 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_WPA
8866 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_RSN
8867#endif
8868 ))
Jeff Johnson295189b2012-06-20 16:38:30 -07008869 {
Nirav Shah4f765af2015-01-21 19:51:30 +05308870 vos_status = wlan_hdd_check_ula_done(pAdapter);
8871
8872 if ( vos_status != VOS_STATUS_SUCCESS )
8873 {
8874 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008875 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8876 __LINE__, vos_status );
8877
Nirav Shah4f765af2015-01-21 19:51:30 +05308878 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008879
Nirav Shah4f765af2015-01-21 19:51:30 +05308880 status = -EINVAL;
8881 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008882
Nirav Shah4f765af2015-01-21 19:51:30 +05308883 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008884 }
8885
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008886#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308887 /* The supplicant may attempt to set the PTK once pre-authentication
8888 is done. Save the key in the UMAC and include it in the ADD BSS
8889 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008890 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308891 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008892 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308893 hddLog(VOS_TRACE_LEVEL_INFO_MED,
8894 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308895 status = 0;
8896 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308897 }
8898 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
8899 {
8900 hddLog(VOS_TRACE_LEVEL_ERROR,
8901 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308902 status = -EINVAL;
8903 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008904 }
8905#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07008906
8907 /* issue set key request to SME*/
8908 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8909 pAdapter->sessionId, &setKey, &roamId );
8910
8911 if ( 0 != status )
8912 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308913 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008914 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
8915 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308916 status = -EINVAL;
8917 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008918 }
8919
8920
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308921 /* in case of IBSS as there was no information available about WEP keys during
8922 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07008923 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308924 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
8925 !( ( IW_AUTH_KEY_MGMT_802_1X
8926 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07008927 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
8928 )
8929 &&
8930 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
8931 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
8932 )
8933 )
8934 {
8935 setKey.keyDirection = eSIR_RX_ONLY;
8936 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8937
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308938 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008939 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308940 __func__, setKey.peerMac[0], setKey.peerMac[1],
8941 setKey.peerMac[2], setKey.peerMac[3],
8942 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008943 setKey.keyDirection);
8944
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308945 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008946 pAdapter->sessionId, &setKey, &roamId );
8947
8948 if ( 0 != status )
8949 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308950 hddLog(VOS_TRACE_LEVEL_ERROR,
8951 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008952 __func__, status);
8953 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308954 status = -EINVAL;
8955 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008956 }
8957 }
8958 }
8959
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308960end:
8961 /* Need to clear any trace of key value in the memory.
8962 * Thus zero out the memory even though it is local
8963 * variable.
8964 */
8965 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308966 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308967 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008968}
8969
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308970#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8971static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8972 struct net_device *ndev,
8973 u8 key_index, bool pairwise,
8974 const u8 *mac_addr,
8975 struct key_params *params
8976 )
8977#else
8978static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8979 struct net_device *ndev,
8980 u8 key_index, const u8 *mac_addr,
8981 struct key_params *params
8982 )
8983#endif
8984{
8985 int ret;
8986 vos_ssr_protect(__func__);
8987#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8988 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
8989 mac_addr, params);
8990#else
8991 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
8992 params);
8993#endif
8994 vos_ssr_unprotect(__func__);
8995
8996 return ret;
8997}
8998
Jeff Johnson295189b2012-06-20 16:38:30 -07008999/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309000 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009001 * This function is used to get the key information
9002 */
9003#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309004static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309005 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009006 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309007 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009008 const u8 *mac_addr, void *cookie,
9009 void (*callback)(void *cookie, struct key_params*)
9010 )
9011#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309012static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309013 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009014 struct net_device *ndev,
9015 u8 key_index, const u8 *mac_addr, void *cookie,
9016 void (*callback)(void *cookie, struct key_params*)
9017 )
9018#endif
9019{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309020 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309021 hdd_wext_state_t *pWextState = NULL;
9022 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009023 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309024 hdd_context_t *pHddCtx;
9025 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009026
9027 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309028
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309029 if (NULL == pAdapter)
9030 {
9031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9032 "%s: HDD adapter is Null", __func__);
9033 return -ENODEV;
9034 }
9035
9036 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9037 ret = wlan_hdd_validate_context(pHddCtx);
9038 if (0 != ret)
9039 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309040 return ret;
9041 }
9042
9043 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9044 pRoamProfile = &(pWextState->roamProfile);
9045
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309046 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9047 __func__, hdd_device_modetoString(pAdapter->device_mode),
9048 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309049
Jeff Johnson295189b2012-06-20 16:38:30 -07009050 memset(&params, 0, sizeof(params));
9051
9052 if (CSR_MAX_NUM_KEY <= key_index)
9053 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309054 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07009055 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309056 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009057
9058 switch(pRoamProfile->EncryptionType.encryptionType[0])
9059 {
9060 case eCSR_ENCRYPT_TYPE_NONE:
9061 params.cipher = IW_AUTH_CIPHER_NONE;
9062 break;
9063
9064 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
9065 case eCSR_ENCRYPT_TYPE_WEP40:
9066 params.cipher = WLAN_CIPHER_SUITE_WEP40;
9067 break;
9068
9069 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
9070 case eCSR_ENCRYPT_TYPE_WEP104:
9071 params.cipher = WLAN_CIPHER_SUITE_WEP104;
9072 break;
9073
9074 case eCSR_ENCRYPT_TYPE_TKIP:
9075 params.cipher = WLAN_CIPHER_SUITE_TKIP;
9076 break;
9077
9078 case eCSR_ENCRYPT_TYPE_AES:
9079 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
9080 break;
9081
9082 default:
9083 params.cipher = IW_AUTH_CIPHER_NONE;
9084 break;
9085 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309086
c_hpothuaaf19692014-05-17 17:01:48 +05309087 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9088 TRACE_CODE_HDD_CFG80211_GET_KEY,
9089 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309090
Jeff Johnson295189b2012-06-20 16:38:30 -07009091 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
9092 params.seq_len = 0;
9093 params.seq = NULL;
9094 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
9095 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309096 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009097 return 0;
9098}
9099
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309100#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9101static int wlan_hdd_cfg80211_get_key(
9102 struct wiphy *wiphy,
9103 struct net_device *ndev,
9104 u8 key_index, bool pairwise,
9105 const u8 *mac_addr, void *cookie,
9106 void (*callback)(void *cookie, struct key_params*)
9107 )
9108#else
9109static int wlan_hdd_cfg80211_get_key(
9110 struct wiphy *wiphy,
9111 struct net_device *ndev,
9112 u8 key_index, const u8 *mac_addr, void *cookie,
9113 void (*callback)(void *cookie, struct key_params*)
9114 )
9115#endif
9116{
9117 int ret;
9118
9119 vos_ssr_protect(__func__);
9120#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9121 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
9122 mac_addr, cookie, callback);
9123#else
9124 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
9125 callback);
9126#endif
9127 vos_ssr_unprotect(__func__);
9128
9129 return ret;
9130}
9131
Jeff Johnson295189b2012-06-20 16:38:30 -07009132/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309133 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009134 * This function is used to delete the key information
9135 */
9136#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309137static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009138 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309139 u8 key_index,
9140 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009141 const u8 *mac_addr
9142 )
9143#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309144static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009145 struct net_device *ndev,
9146 u8 key_index,
9147 const u8 *mac_addr
9148 )
9149#endif
9150{
9151 int status = 0;
9152
9153 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309154 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009155 //it is observed that this is invalidating peer
9156 //key index whenever re-key is done. This is affecting data link.
9157 //It should be ok to ignore del_key.
9158#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309159 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
9160 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009161 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
9162 tCsrRoamSetKey setKey;
9163 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309164
Jeff Johnson295189b2012-06-20 16:38:30 -07009165 ENTER();
9166
9167 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
9168 __func__,pAdapter->device_mode);
9169
9170 if (CSR_MAX_NUM_KEY <= key_index)
9171 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309172 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009173 key_index);
9174
9175 return -EINVAL;
9176 }
9177
9178 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9179 setKey.keyId = key_index;
9180
9181 if (mac_addr)
9182 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9183 else
9184 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
9185
9186 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
9187
9188 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009189 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309190 )
9191 {
9192
9193 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07009194 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9195 if( pHostapdState->bssState == BSS_START)
9196 {
9197 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309198
Jeff Johnson295189b2012-06-20 16:38:30 -07009199 if ( status != eHAL_STATUS_SUCCESS )
9200 {
9201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9202 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9203 __LINE__, status );
9204 }
9205 }
9206 }
9207 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309208 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07009209 )
9210 {
9211 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9212
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309213 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9214
9215 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009216 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309217 __func__, setKey.peerMac[0], setKey.peerMac[1],
9218 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07009219 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309220 if(pAdapter->sessionCtx.station.conn_info.connState ==
9221 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07009222 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309223 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009224 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309225
Jeff Johnson295189b2012-06-20 16:38:30 -07009226 if ( 0 != status )
9227 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309228 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009229 "%s: sme_RoamSetKey failure, returned %d",
9230 __func__, status);
9231 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9232 return -EINVAL;
9233 }
9234 }
9235 }
9236#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009237 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009238 return status;
9239}
9240
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309241#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9242static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9243 struct net_device *ndev,
9244 u8 key_index,
9245 bool pairwise,
9246 const u8 *mac_addr
9247 )
9248#else
9249static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9250 struct net_device *ndev,
9251 u8 key_index,
9252 const u8 *mac_addr
9253 )
9254#endif
9255{
9256 int ret;
9257
9258 vos_ssr_protect(__func__);
9259#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9260 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
9261 mac_addr);
9262#else
9263 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
9264#endif
9265 vos_ssr_unprotect(__func__);
9266
9267 return ret;
9268}
9269
Jeff Johnson295189b2012-06-20 16:38:30 -07009270/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309271 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009272 * This function is used to set the default tx key index
9273 */
9274#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309275static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009276 struct net_device *ndev,
9277 u8 key_index,
9278 bool unicast, bool multicast)
9279#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309280static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009281 struct net_device *ndev,
9282 u8 key_index)
9283#endif
9284{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309285 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309286 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309287 hdd_wext_state_t *pWextState;
9288 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309289 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009290
9291 ENTER();
9292
Gopichand Nakkala29149562013-05-10 21:43:41 +05309293 if ((NULL == pAdapter))
9294 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309295 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309296 "invalid adapter");
9297 return -EINVAL;
9298 }
9299
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309300 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9301 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
9302 pAdapter->sessionId, key_index));
9303
Gopichand Nakkala29149562013-05-10 21:43:41 +05309304 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9305 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9306
9307 if ((NULL == pWextState) || (NULL == pHddStaCtx))
9308 {
9309 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9310 "invalid Wext state or HDD context");
9311 return -EINVAL;
9312 }
9313
Arif Hussain6d2a3322013-11-17 19:50:10 -08009314 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009315 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309316
Jeff Johnson295189b2012-06-20 16:38:30 -07009317 if (CSR_MAX_NUM_KEY <= key_index)
9318 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309319 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009320 key_index);
9321
9322 return -EINVAL;
9323 }
9324
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309325 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9326 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309327 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009328 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309329 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009330 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309331
Jeff Johnson295189b2012-06-20 16:38:30 -07009332 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07009333 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309334 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009335 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309336 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08009337 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309338 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08009339 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07009340 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309341 {
9342 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07009343 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309344
Jeff Johnson295189b2012-06-20 16:38:30 -07009345 tCsrRoamSetKey setKey;
9346 v_U32_t roamId= 0xFF;
9347 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309348
9349 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009350 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309351
Jeff Johnson295189b2012-06-20 16:38:30 -07009352 Keys->defaultIndex = (u8)key_index;
9353 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9354 setKey.keyId = key_index;
9355 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309356
9357 vos_mem_copy(&setKey.Key[0],
9358 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009359 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309360
Gopichand Nakkala29149562013-05-10 21:43:41 +05309361 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309362
9363 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07009364 &pHddStaCtx->conn_info.bssId[0],
9365 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309366
Gopichand Nakkala29149562013-05-10 21:43:41 +05309367 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
9368 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
9369 eCSR_ENCRYPT_TYPE_WEP104)
9370 {
9371 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
9372 even though ap is configured for WEP-40 encryption. In this canse the key length
9373 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
9374 type(104) and switching encryption type to 40*/
9375 pWextState->roamProfile.EncryptionType.encryptionType[0] =
9376 eCSR_ENCRYPT_TYPE_WEP40;
9377 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
9378 eCSR_ENCRYPT_TYPE_WEP40;
9379 }
9380
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309381 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07009382 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309383
Jeff Johnson295189b2012-06-20 16:38:30 -07009384 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309385 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009386 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309387
Jeff Johnson295189b2012-06-20 16:38:30 -07009388 if ( 0 != status )
9389 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309390 hddLog(VOS_TRACE_LEVEL_ERROR,
9391 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 status);
9393 return -EINVAL;
9394 }
9395 }
9396 }
9397
9398 /* In SoftAp mode setting key direction for default mode */
9399 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
9400 {
9401 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
9402 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
9403 (eCSR_ENCRYPT_TYPE_AES !=
9404 pWextState->roamProfile.EncryptionType.encryptionType[0])
9405 )
9406 {
9407 /* Saving key direction for default key index to TX default */
9408 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9409 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
9410 }
9411 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309412 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009413 return status;
9414}
9415
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309416#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9417static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9418 struct net_device *ndev,
9419 u8 key_index,
9420 bool unicast, bool multicast)
9421#else
9422static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9423 struct net_device *ndev,
9424 u8 key_index)
9425#endif
9426{
9427 int ret;
9428 vos_ssr_protect(__func__);
9429#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9430 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
9431 multicast);
9432#else
9433 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
9434#endif
9435 vos_ssr_unprotect(__func__);
9436
9437 return ret;
9438}
9439
Jeff Johnson295189b2012-06-20 16:38:30 -07009440/*
9441 * FUNCTION: wlan_hdd_cfg80211_inform_bss
9442 * This function is used to inform the BSS details to nl80211 interface.
9443 */
9444static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
9445 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
9446{
9447 struct net_device *dev = pAdapter->dev;
9448 struct wireless_dev *wdev = dev->ieee80211_ptr;
9449 struct wiphy *wiphy = wdev->wiphy;
9450 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
9451 int chan_no;
9452 int ie_length;
9453 const char *ie;
9454 unsigned int freq;
9455 struct ieee80211_channel *chan;
9456 int rssi = 0;
9457 struct cfg80211_bss *bss = NULL;
9458
9459 ENTER();
9460
9461 if( NULL == pBssDesc )
9462 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009463 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009464 return bss;
9465 }
9466
9467 chan_no = pBssDesc->channelId;
9468 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
9469 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
9470
9471 if( NULL == ie )
9472 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009473 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009474 return bss;
9475 }
9476
9477#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9478 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9479 {
9480 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9481 }
9482 else
9483 {
9484 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9485 }
9486#else
9487 freq = ieee80211_channel_to_frequency(chan_no);
9488#endif
9489
9490 chan = __ieee80211_get_channel(wiphy, freq);
9491
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05309492 if (!chan) {
9493 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
9494 return NULL;
9495 }
9496
Abhishek Singhaee43942014-06-16 18:55:47 +05309497 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07009498
Abhishek Singhaee43942014-06-16 18:55:47 +05309499 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309500 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07009501 pBssDesc->capabilityInfo,
9502 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05309503 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07009504}
9505
9506
9507
9508/*
9509 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
9510 * This function is used to inform the BSS details to nl80211 interface.
9511 */
9512struct cfg80211_bss*
9513wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9514 tSirBssDescription *bss_desc
9515 )
9516{
9517 /*
9518 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9519 already exists in bss data base of cfg80211 for that particular BSS ID.
9520 Using cfg80211_inform_bss_frame to update the bss entry instead of
9521 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9522 now there is no possibility to get the mgmt(probe response) frame from PE,
9523 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9524 cfg80211_inform_bss_frame.
9525 */
9526 struct net_device *dev = pAdapter->dev;
9527 struct wireless_dev *wdev = dev->ieee80211_ptr;
9528 struct wiphy *wiphy = wdev->wiphy;
9529 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009530#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9531 qcom_ie_age *qie_age = NULL;
9532 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9533#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009534 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009535#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009536 const char *ie =
9537 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9538 unsigned int freq;
9539 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309540 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009541 struct cfg80211_bss *bss_status = NULL;
9542 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9543 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009544 hdd_context_t *pHddCtx;
9545 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009546#ifdef WLAN_OPEN_SOURCE
9547 struct timespec ts;
9548#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009549
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309550 ENTER();
9551
Wilson Yangf80a0542013-10-07 13:02:37 -07009552 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9553 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -07009554 if (0 != status)
9555 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009556 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009557 }
9558
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309559 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009560 if (!mgmt)
9561 {
9562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9563 "%s: memory allocation failed ", __func__);
9564 return NULL;
9565 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009566
Jeff Johnson295189b2012-06-20 16:38:30 -07009567 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07009568
9569#ifdef WLAN_OPEN_SOURCE
9570 /* Android does not want the timestamp from the frame.
9571 Instead it wants a monotonic increasing value */
9572 get_monotonic_boottime(&ts);
9573 mgmt->u.probe_resp.timestamp =
9574 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
9575#else
9576 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009577 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
9578 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07009579
9580#endif
9581
Jeff Johnson295189b2012-06-20 16:38:30 -07009582 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
9583 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009584
9585#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9586 /* GPS Requirement: need age ie per entry. Using vendor specific. */
9587 /* Assuming this is the last IE, copy at the end */
9588 ie_length -=sizeof(qcom_ie_age);
9589 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
9590 qie_age->element_id = QCOM_VENDOR_IE_ID;
9591 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
9592 qie_age->oui_1 = QCOM_OUI1;
9593 qie_age->oui_2 = QCOM_OUI2;
9594 qie_age->oui_3 = QCOM_OUI3;
9595 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
9596 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
9597#endif
9598
Jeff Johnson295189b2012-06-20 16:38:30 -07009599 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05309600 if (bss_desc->fProbeRsp)
9601 {
9602 mgmt->frame_control |=
9603 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
9604 }
9605 else
9606 {
9607 mgmt->frame_control |=
9608 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
9609 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009610
9611#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309612 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009613 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
9614 {
9615 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9616 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309617 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009618 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
9619
9620 {
9621 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9622 }
9623 else
9624 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309625 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
9626 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07009627 kfree(mgmt);
9628 return NULL;
9629 }
9630#else
9631 freq = ieee80211_channel_to_frequency(chan_no);
9632#endif
9633 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009634 /*when the band is changed on the fly using the GUI, three things are done
9635 * 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)
9636 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
9637 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
9638 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
9639 * and discards the channels correponding to previous band and calls back with zero bss results.
9640 * 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
9641 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
9642 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
9643 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
9644 * So drop the bss and continue to next bss.
9645 */
9646 if(chan == NULL)
9647 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309648 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07009649 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009650 return NULL;
9651 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009652 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309653 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07009654 * */
9655 if (( eConnectionState_Associated ==
9656 pAdapter->sessionCtx.station.conn_info.connState ) &&
9657 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
9658 pAdapter->sessionCtx.station.conn_info.bssId,
9659 WNI_CFG_BSSID_LEN)))
9660 {
9661 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
9662 rssi = (pAdapter->rssi * 100);
9663 }
9664 else
9665 {
9666 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
9667 }
9668
Nirav Shah20ac06f2013-12-12 18:14:06 +05309669 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
9670 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
9671 chan->center_freq, (int)(rssi/100));
9672
Jeff Johnson295189b2012-06-20 16:38:30 -07009673 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
9674 frame_len, rssi, GFP_KERNEL);
9675 kfree(mgmt);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309676 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009677 return bss_status;
9678}
9679
9680/*
9681 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
9682 * This function is used to update the BSS data base of CFG8011
9683 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309684struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009685 tCsrRoamInfo *pRoamInfo
9686 )
9687{
9688 tCsrRoamConnectedProfile roamProfile;
9689 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9690 struct cfg80211_bss *bss = NULL;
9691
9692 ENTER();
9693
9694 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
9695 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
9696
9697 if (NULL != roamProfile.pBssDesc)
9698 {
Girish Gowlif4b68022014-08-28 23:18:57 +05309699 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9700 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009701
9702 if (NULL == bss)
9703 {
9704 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
9705 __func__);
9706 }
9707
9708 sme_RoamFreeConnectProfile(hHal, &roamProfile);
9709 }
9710 else
9711 {
9712 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
9713 __func__);
9714 }
9715 return bss;
9716}
9717
9718/*
9719 * FUNCTION: wlan_hdd_cfg80211_update_bss
9720 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309721static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
9722 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07009723 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309724{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309725 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009726 tCsrScanResultInfo *pScanResult;
9727 eHalStatus status = 0;
9728 tScanResultHandle pResult;
9729 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009730 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009731
9732 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309733
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309734 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9735 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
9736 NO_SESSION, pAdapter->sessionId));
9737
Wilson Yangf80a0542013-10-07 13:02:37 -07009738 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9739
9740 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009741 {
Wilson Yangf80a0542013-10-07 13:02:37 -07009742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9743 "%s:LOGP in Progress. Ignore!!!",__func__);
9744 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009745 }
9746
Wilson Yangf80a0542013-10-07 13:02:37 -07009747
9748 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309749 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009750 {
9751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9752 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9753 return VOS_STATUS_E_PERM;
9754 }
9755
9756
Jeff Johnson295189b2012-06-20 16:38:30 -07009757 /*
9758 * start getting scan results and populate cgf80211 BSS database
9759 */
9760 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
9761
9762 /* no scan results */
9763 if (NULL == pResult)
9764 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309765 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
9766 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009767 return status;
9768 }
9769
9770 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
9771
9772 while (pScanResult)
9773 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309774 /*
9775 * cfg80211_inform_bss() is not updating ie field of bss entry, if
9776 * entry already exists in bss data base of cfg80211 for that
9777 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
9778 * bss entry instead of cfg80211_inform_bss, But this call expects
9779 * mgmt packet as input. As of now there is no possibility to get
9780 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07009781 * ieee80211_mgmt(probe response) and passing to c
9782 * fg80211_inform_bss_frame.
9783 * */
9784
9785 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9786 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309787
Jeff Johnson295189b2012-06-20 16:38:30 -07009788
9789 if (NULL == bss_status)
9790 {
9791 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009792 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009793 }
9794 else
9795 {
Yue Maf49ba872013-08-19 12:04:25 -07009796 cfg80211_put_bss(
9797#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
9798 wiphy,
9799#endif
9800 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009801 }
9802
9803 pScanResult = sme_ScanResultGetNext(hHal, pResult);
9804 }
9805
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309806 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07009807
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309808 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009809}
9810
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009811void
9812hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
9813{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309814 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08009815 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009816} /****** end hddPrintMacAddr() ******/
9817
9818void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009819hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009820{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309821 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009822 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009823 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
9824 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
9825 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009826} /****** end hddPrintPmkId() ******/
9827
9828//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
9829//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
9830
9831//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
9832//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
9833
9834#define dump_bssid(bssid) \
9835 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009836 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
9837 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009838 }
9839
9840#define dump_pmkid(pMac, pmkid) \
9841 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009842 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
9843 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009844 }
9845
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009846#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009847/*
9848 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
9849 * This function is used to notify the supplicant of a new PMKSA candidate.
9850 */
9851int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309852 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009853 int index, bool preauth )
9854{
Jeff Johnsone7245742012-09-05 17:12:55 -07009855#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009856 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009857 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009858
9859 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07009860 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009861
9862 if( NULL == pRoamInfo )
9863 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009864 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009865 return -EINVAL;
9866 }
9867
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009868 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
9869 {
9870 dump_bssid(pRoamInfo->bssid);
9871 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009872 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009873 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009874#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309875 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009876}
9877#endif //FEATURE_WLAN_LFR
9878
Yue Maef608272013-04-08 23:09:17 -07009879#ifdef FEATURE_WLAN_LFR_METRICS
9880/*
9881 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
9882 * 802.11r/LFR metrics reporting function to report preauth initiation
9883 *
9884 */
9885#define MAX_LFR_METRICS_EVENT_LENGTH 100
9886VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
9887 tCsrRoamInfo *pRoamInfo)
9888{
9889 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9890 union iwreq_data wrqu;
9891
9892 ENTER();
9893
9894 if (NULL == pAdapter)
9895 {
9896 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9897 return VOS_STATUS_E_FAILURE;
9898 }
9899
9900 /* create the event */
9901 memset(&wrqu, 0, sizeof(wrqu));
9902 memset(metrics_notification, 0, sizeof(metrics_notification));
9903
9904 wrqu.data.pointer = metrics_notification;
9905 wrqu.data.length = scnprintf(metrics_notification,
9906 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
9907 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9908
9909 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9910
9911 EXIT();
9912
9913 return VOS_STATUS_SUCCESS;
9914}
9915
9916/*
9917 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
9918 * 802.11r/LFR metrics reporting function to report preauth completion
9919 * or failure
9920 */
9921VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
9922 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
9923{
9924 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9925 union iwreq_data wrqu;
9926
9927 ENTER();
9928
9929 if (NULL == pAdapter)
9930 {
9931 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9932 return VOS_STATUS_E_FAILURE;
9933 }
9934
9935 /* create the event */
9936 memset(&wrqu, 0, sizeof(wrqu));
9937 memset(metrics_notification, 0, sizeof(metrics_notification));
9938
9939 scnprintf(metrics_notification, sizeof(metrics_notification),
9940 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
9941 MAC_ADDR_ARRAY(pRoamInfo->bssid));
9942
9943 if (1 == preauth_status)
9944 strncat(metrics_notification, " TRUE", 5);
9945 else
9946 strncat(metrics_notification, " FALSE", 6);
9947
9948 wrqu.data.pointer = metrics_notification;
9949 wrqu.data.length = strlen(metrics_notification);
9950
9951 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9952
9953 EXIT();
9954
9955 return VOS_STATUS_SUCCESS;
9956}
9957
9958/*
9959 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
9960 * 802.11r/LFR metrics reporting function to report handover initiation
9961 *
9962 */
9963VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
9964 tCsrRoamInfo *pRoamInfo)
9965{
9966 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9967 union iwreq_data wrqu;
9968
9969 ENTER();
9970
9971 if (NULL == pAdapter)
9972 {
9973 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9974 return VOS_STATUS_E_FAILURE;
9975 }
9976
9977 /* create the event */
9978 memset(&wrqu, 0, sizeof(wrqu));
9979 memset(metrics_notification, 0, sizeof(metrics_notification));
9980
9981 wrqu.data.pointer = metrics_notification;
9982 wrqu.data.length = scnprintf(metrics_notification,
9983 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
9984 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9985
9986 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9987
9988 EXIT();
9989
9990 return VOS_STATUS_SUCCESS;
9991}
9992#endif
9993
Jeff Johnson295189b2012-06-20 16:38:30 -07009994/*
9995 * FUNCTION: hdd_cfg80211_scan_done_callback
9996 * scanning callback function, called after finishing scan
9997 *
9998 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309999static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070010000 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
10001{
10002 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010003 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070010004 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010005 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10006 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -070010007 struct cfg80211_scan_request *req = NULL;
10008 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010009 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010010 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010011 tANI_U8 i;
Jeff Johnson295189b2012-06-20 16:38:30 -070010012
10013 ENTER();
10014
10015 hddLog(VOS_TRACE_LEVEL_INFO,
10016 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080010017 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010018 __func__, halHandle, pContext, (int) scanId, (int) status);
10019
Kiet Lamac06e2c2013-10-23 16:25:07 +053010020 pScanInfo->mScanPendingCounter = 0;
10021
Jeff Johnson295189b2012-06-20 16:38:30 -070010022 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010023 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010024 &pScanInfo->scan_req_completion_event,
10025 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010026 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070010027 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010028 hddLog(VOS_TRACE_LEVEL_ERROR,
10029 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070010030 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010031 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010032 }
10033
Yue Maef608272013-04-08 23:09:17 -070010034 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010035 {
10036 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010037 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010038 }
10039
10040 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010041 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070010042 {
10043 hddLog(VOS_TRACE_LEVEL_INFO,
10044 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010045 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070010046 (int) scanId);
10047 }
10048
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010049 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010050 pAdapter);
10051
10052 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010053 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010054
10055
10056 /* If any client wait scan result through WEXT
10057 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010058 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070010059 {
10060 /* The other scan request waiting for current scan finish
10061 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010062 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010063 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010064 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070010065 }
10066 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010067 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010068 {
10069 struct net_device *dev = pAdapter->dev;
10070 union iwreq_data wrqu;
10071 int we_event;
10072 char *msg;
10073
10074 memset(&wrqu, '\0', sizeof(wrqu));
10075 we_event = SIOCGIWSCAN;
10076 msg = NULL;
10077 wireless_send_event(dev, we_event, &wrqu, msg);
10078 }
10079 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010080 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010081
10082 /* Get the Scan Req */
10083 req = pAdapter->request;
10084
10085 if (!req)
10086 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010087 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010088 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010089 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010090 }
10091
Jeff Johnson295189b2012-06-20 16:38:30 -070010092 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070010093 /* Scan is no longer pending */
10094 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010095
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010096 /* last_scan_timestamp is used to decide if new scan
10097 * is needed or not on station interface. If last station
10098 * scan time and new station scan time is less then
10099 * last_scan_timestamp ; driver will return cached scan.
10100 */
10101 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
10102 {
10103 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
10104
10105 if ( req->n_channels )
10106 {
10107 for (i = 0; i < req->n_channels ; i++ )
10108 {
10109 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
10110 }
10111 /* store no of channel scanned */
10112 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
10113 }
10114
10115 }
10116
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070010117 /*
10118 * cfg80211_scan_done informing NL80211 about completion
10119 * of scanning
10120 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010121 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
10122 {
10123 aborted = true;
10124 }
10125 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080010126 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010127
Siddharth Bhal76972212014-10-15 16:22:51 +053010128 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
10129 /* Generate new random mac addr for next scan */
10130 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
10131 hdd_processSpoofMacAddrRequest(pHddCtx);
10132 }
10133
Jeff Johnsone7245742012-09-05 17:12:55 -070010134allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010135 /* release the wake lock at the end of the scan*/
10136 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -070010137
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010138 /* Acquire wakelock to handle the case where APP's tries to suspend
10139 * immediatly after the driver gets connect request(i.e after scan)
10140 * from supplicant, this result in app's is suspending and not able
10141 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010142 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010143
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010144#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010145 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010146#endif
10147
Jeff Johnson295189b2012-06-20 16:38:30 -070010148 EXIT();
10149 return 0;
10150}
10151
10152/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053010153 * FUNCTION: hdd_isConnectionInProgress
10154 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010155 *
10156 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010157v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010158{
10159 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10160 hdd_station_ctx_t *pHddStaCtx = NULL;
10161 hdd_adapter_t *pAdapter = NULL;
10162 VOS_STATUS status = 0;
10163 v_U8_t staId = 0;
10164 v_U8_t *staMac = NULL;
10165
c_hpothu9b781ba2013-12-30 20:57:45 +053010166 if (TRUE == pHddCtx->btCoexModeSet)
10167 {
10168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053010169 FL("BTCoex Mode operation in progress"));
10170 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053010171 }
10172
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010173 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10174
10175 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10176 {
10177 pAdapter = pAdapterNode->pAdapter;
10178
10179 if( pAdapter )
10180 {
10181 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010182 "%s: Adapter with device mode %s (%d) exists",
10183 __func__, hdd_device_modetoString(pAdapter->device_mode),
10184 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010185 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053010186 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10187 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
10188 (eConnectionState_Connecting ==
10189 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
10190 {
10191 hddLog(VOS_TRACE_LEVEL_ERROR,
10192 "%s: %p(%d) Connection is in progress", __func__,
10193 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10194 return VOS_TRUE;
10195 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010196 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053010197 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010198 {
10199 hddLog(VOS_TRACE_LEVEL_ERROR,
10200 "%s: %p(%d) Reassociation is in progress", __func__,
10201 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10202 return VOS_TRUE;
10203 }
10204 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010205 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10206 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010207 {
10208 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10209 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010210 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010211 {
10212 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
10213 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010214 "%s: client " MAC_ADDRESS_STR
10215 " is in the middle of WPS/EAPOL exchange.", __func__,
10216 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010217 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010218 }
10219 }
10220 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
10221 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
10222 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010223 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10224 ptSapContext pSapCtx = NULL;
10225 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10226 if(pSapCtx == NULL){
10227 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10228 FL("psapCtx is NULL"));
10229 return VOS_FALSE;
10230 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010231 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
10232 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010233 if ((pSapCtx->aStaInfo[staId].isUsed) &&
10234 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010235 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010236 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010237
10238 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010239 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
10240 "middle of WPS/EAPOL exchange.", __func__,
10241 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010242 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010243 }
10244 }
10245 }
10246 }
10247 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10248 pAdapterNode = pNext;
10249 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053010250 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010251}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010252
10253/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010254 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070010255 * this scan respond to scan trigger and update cfg80211 scan database
10256 * later, scan dump command can be used to recieve scan results
10257 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010258int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010259#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10260 struct net_device *dev,
10261#endif
10262 struct cfg80211_scan_request *request)
10263{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010264 hdd_adapter_t *pAdapter = NULL;
10265 hdd_context_t *pHddCtx = NULL;
10266 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010267 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010268 tCsrScanRequest scanRequest;
10269 tANI_U8 *channelList = NULL, i;
10270 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010271 int status;
10272 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010273 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010274 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010275
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010276#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
10277 struct net_device *dev = NULL;
10278 if (NULL == request)
10279 {
10280 hddLog(VOS_TRACE_LEVEL_ERROR,
10281 "%s: scan req param null", __func__);
10282 return -EINVAL;
10283 }
10284 dev = request->wdev->netdev;
10285#endif
10286
10287 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
10288 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
10289 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10290
Jeff Johnson295189b2012-06-20 16:38:30 -070010291 ENTER();
10292
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010293 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10294 __func__, hdd_device_modetoString(pAdapter->device_mode),
10295 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010296
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010297 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010298 if (0 != status)
10299 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010300 return status;
10301 }
10302
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010303 if (NULL == pwextBuf)
10304 {
10305 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
10306 __func__);
10307 return -EIO;
10308 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010309 cfg_param = pHddCtx->cfg_ini;
10310 pScanInfo = &pHddCtx->scan_info;
10311
Jeff Johnson295189b2012-06-20 16:38:30 -070010312#ifdef WLAN_BTAMP_FEATURE
10313 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010314 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070010315 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010316 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010317 "%s: No scanning when AMP is on", __func__);
10318 return -EOPNOTSUPP;
10319 }
10320#endif
10321 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010322 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010323 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010324 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010325 "%s: Not scanning on device_mode = %s (%d)",
10326 __func__, hdd_device_modetoString(pAdapter->device_mode),
10327 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010328 return -EOPNOTSUPP;
10329 }
10330
10331 if (TRUE == pScanInfo->mScanPending)
10332 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010333 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
10334 {
10335 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
10336 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010337 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010338 }
10339
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010340 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070010341 //Channel and action frame is pending
10342 //Otherwise Cancel Remain On Channel and allow Scan
10343 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010344 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070010345 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010346 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010347 return -EBUSY;
10348 }
10349
Jeff Johnson295189b2012-06-20 16:38:30 -070010350 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
10351 {
10352 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080010353 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010354 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010355 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010356 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
10357 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010358 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010359 "%s: MAX TM Level Scan not allowed", __func__);
10360 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010361 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010362 }
10363 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
10364
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010365 /* Check if scan is allowed at this point of time.
10366 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010367 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010368 {
10369 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
10370 return -EBUSY;
10371 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010372
Jeff Johnson295189b2012-06-20 16:38:30 -070010373 vos_mem_zero( &scanRequest, sizeof(scanRequest));
10374
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010375 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
10376 (int)request->n_ssids);
10377
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010378
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010379 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
10380 * Becasue of this, driver is assuming that this is not wildcard scan and so
10381 * is not aging out the scan results.
10382 */
10383 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010384 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010385 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010386 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010387
10388 if ((request->ssids) && (0 < request->n_ssids))
10389 {
10390 tCsrSSIDInfo *SsidInfo;
10391 int j;
10392 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
10393 /* Allocate num_ssid tCsrSSIDInfo structure */
10394 SsidInfo = scanRequest.SSIDs.SSIDList =
10395 ( tCsrSSIDInfo *)vos_mem_malloc(
10396 request->n_ssids*sizeof(tCsrSSIDInfo));
10397
10398 if(NULL == scanRequest.SSIDs.SSIDList)
10399 {
10400 hddLog(VOS_TRACE_LEVEL_ERROR,
10401 "%s: memory alloc failed SSIDInfo buffer", __func__);
10402 return -ENOMEM;
10403 }
10404
10405 /* copy all the ssid's and their length */
10406 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
10407 {
10408 /* get the ssid length */
10409 SsidInfo->SSID.length = request->ssids[j].ssid_len;
10410 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
10411 SsidInfo->SSID.length);
10412 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
10413 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
10414 j, SsidInfo->SSID.ssId);
10415 }
10416 /* set the scan type to active */
10417 scanRequest.scanType = eSIR_ACTIVE_SCAN;
10418 }
10419 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070010420 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010421 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10422 TRACE_CODE_HDD_CFG80211_SCAN,
10423 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070010424 /* set the scan type to active */
10425 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010426 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010427 else
10428 {
10429 /*Set the scan type to default type, in this case it is ACTIVE*/
10430 scanRequest.scanType = pScanInfo->scan_mode;
10431 }
10432 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
10433 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070010434
10435 /* set BSSType to default type */
10436 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
10437
10438 /*TODO: scan the requested channels only*/
10439
10440 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010441 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070010442 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010443 hddLog(VOS_TRACE_LEVEL_WARN,
10444 "No of Scan Channels exceeded limit: %d", request->n_channels);
10445 request->n_channels = MAX_CHANNEL;
10446 }
10447
10448 hddLog(VOS_TRACE_LEVEL_INFO,
10449 "No of Scan Channels: %d", request->n_channels);
10450
10451
10452 if( request->n_channels )
10453 {
10454 char chList [(request->n_channels*5)+1];
10455 int len;
10456 channelList = vos_mem_malloc( request->n_channels );
10457 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053010458 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010459 hddLog(VOS_TRACE_LEVEL_ERROR,
10460 "%s: memory alloc failed channelList", __func__);
10461 status = -ENOMEM;
10462 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053010463 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010464
10465 for( i = 0, len = 0; i < request->n_channels ; i++ )
10466 {
10467 channelList[i] = request->channels[i]->hw_value;
10468 len += snprintf(chList+len, 5, "%d ", channelList[i]);
10469 }
10470
Nirav Shah20ac06f2013-12-12 18:14:06 +053010471 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010472 "Channel-List: %s ", chList);
10473 }
c_hpothu53512302014-04-15 18:49:53 +053010474
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010475 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
10476 scanRequest.ChannelInfo.ChannelList = channelList;
10477
10478 /* set requestType to full scan */
10479 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10480
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010481 /* if there is back to back scan happening in driver with in
10482 * nDeferScanTimeInterval interval driver should defer new scan request
10483 * and should provide last cached scan results instead of new channel list.
10484 * This rule is not applicable if scan is p2p scan.
10485 * This condition will work only in case when last request no of channels
10486 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053010487 * This should be done only in connected state
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010488 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010489
Agarwal Ashish57e84372014-12-05 18:26:53 +053010490 if ((VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
10491 {
10492 if ( pScanInfo->last_scan_timestamp !=0 &&
10493 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10494 {
10495 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
10496 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
10497 vos_mem_compare(pScanInfo->last_scan_channelList,
10498 channelList, pScanInfo->last_scan_numChannels))
10499 {
10500 hddLog(VOS_TRACE_LEVEL_WARN,
10501 " New and old station scan time differ is less then %u",
10502 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10503
10504 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010505 pAdapter);
10506
Agarwal Ashish57e84372014-12-05 18:26:53 +053010507 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010508 "Return old cached scan as all channels and no of channels are same");
10509
Agarwal Ashish57e84372014-12-05 18:26:53 +053010510 if (0 > ret)
10511 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010512
Agarwal Ashish57e84372014-12-05 18:26:53 +053010513 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010514
10515 status = eHAL_STATUS_SUCCESS;
10516 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053010517 }
10518 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010519 }
10520
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010521 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10522 * search (Flush on both full scan and social scan but not on single
10523 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10524 */
10525
10526 /* Supplicant does single channel scan after 8-way handshake
10527 * and in that case driver shoudnt flush scan results. If
10528 * driver flushes the scan results here and unfortunately if
10529 * the AP doesnt respond to our probe req then association
10530 * fails which is not desired
10531 */
10532
10533 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
10534 {
10535 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
10536 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
10537 pAdapter->sessionId );
10538 }
10539
10540 if( request->ie_len )
10541 {
10542 /* save this for future association (join requires this) */
10543 /*TODO: Array needs to be converted to dynamic allocation,
10544 * as multiple ie.s can be sent in cfg80211_scan_request structure
10545 * CR 597966
10546 */
10547 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
10548 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
10549 pScanInfo->scanAddIE.length = request->ie_len;
10550
10551 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10552 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10553 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010554 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010555 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070010556 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010557 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
10558 memcpy( pwextBuf->roamProfile.addIEScan,
10559 request->ie, request->ie_len);
10560 }
10561 else
10562 {
10563 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
10564 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070010565 }
10566
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010567 }
10568 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
10569 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
10570
10571 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
10572 request->ie_len);
10573 if (pP2pIe != NULL)
10574 {
10575#ifdef WLAN_FEATURE_P2P_DEBUG
10576 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
10577 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
10578 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053010579 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010580 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
10581 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10582 "Go nego completed to Connection is started");
10583 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10584 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053010585 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010586 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
10587 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010588 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010589 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
10590 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10591 "Disconnected state to Connection is started");
10592 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10593 "for 4way Handshake");
10594 }
10595#endif
10596
10597 /* no_cck will be set during p2p find to disable 11b rates */
10598 if(TRUE == request->no_cck)
10599 {
10600 hddLog(VOS_TRACE_LEVEL_INFO,
10601 "%s: This is a P2P Search", __func__);
10602 scanRequest.p2pSearch = 1;
10603
10604 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053010605 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010606 /* set requestType to P2P Discovery */
10607 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
10608 }
10609
10610 /*
10611 Skip Dfs Channel in case of P2P Search
10612 if it is set in ini file
10613 */
10614 if(cfg_param->skipDfsChnlInP2pSearch)
10615 {
10616 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010617 }
10618 else
10619 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010620 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010621 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010622
Agarwal Ashish4f616132013-12-30 23:32:50 +053010623 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010624 }
10625 }
10626
10627 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
10628
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010629#ifdef FEATURE_WLAN_TDLS
10630 /* if tdls disagree scan right now, return immediately.
10631 tdls will schedule the scan when scan is allowed. (return SUCCESS)
10632 or will reject the scan if any TDLS is in progress. (return -EBUSY)
10633 */
10634 status = wlan_hdd_tdls_scan_callback (pAdapter,
10635 wiphy,
10636#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10637 dev,
10638#endif
10639 request);
10640 if(status <= 0)
10641 {
10642 if(!status)
10643 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
10644 "scan rejected %d", __func__, status);
10645 else
10646 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
10647 __func__, status);
10648
10649 return status;
10650 }
10651#endif
10652
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010653 /* acquire the wakelock to avoid the apps suspend during the scan. To
10654 * address the following issues.
10655 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
10656 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
10657 * for long time, this result in apps running at full power for long time.
10658 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
10659 * be stuck in full power because of resume BMPS
10660 */
10661 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -070010662
Nirav Shah20ac06f2013-12-12 18:14:06 +053010663 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10664 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010665 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
10666 scanRequest.requestType, scanRequest.scanType,
10667 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053010668 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
10669
Siddharth Bhal76972212014-10-15 16:22:51 +053010670 if (pHddCtx->spoofMacAddr.isEnabled)
10671 {
10672 hddLog(VOS_TRACE_LEVEL_INFO,
10673 "%s: MAC Spoofing enabled for current scan", __func__);
10674 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
10675 * to fill TxBds for probe request during current scan
10676 */
10677 WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
10678 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
10679 }
10680
Jeff Johnsone7245742012-09-05 17:12:55 -070010681 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010682 pAdapter->sessionId, &scanRequest, &scanId,
10683 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070010684
Jeff Johnson295189b2012-06-20 16:38:30 -070010685 if (eHAL_STATUS_SUCCESS != status)
10686 {
10687 hddLog(VOS_TRACE_LEVEL_ERROR,
10688 "%s: sme_ScanRequest returned error %d", __func__, status);
10689 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010690 if(eHAL_STATUS_RESOURCES == status)
10691 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010692 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
10693 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010694 status = -EBUSY;
10695 } else {
10696 status = -EIO;
10697 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010698 hdd_allow_suspend();
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010699
10700#ifdef FEATURE_WLAN_TDLS
10701 wlan_hdd_tdls_scan_done_callback(pAdapter);
10702#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010703 goto free_mem;
10704 }
10705
10706 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010707 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070010708 pAdapter->request = request;
10709 pScanInfo->scanId = scanId;
10710
10711 complete(&pScanInfo->scan_req_completion_event);
10712
10713free_mem:
10714 if( scanRequest.SSIDs.SSIDList )
10715 {
10716 vos_mem_free(scanRequest.SSIDs.SSIDList);
10717 }
10718
10719 if( channelList )
10720 vos_mem_free( channelList );
10721
10722 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010723 return status;
10724}
10725
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010726int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
10727#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10728 struct net_device *dev,
10729#endif
10730 struct cfg80211_scan_request *request)
10731{
10732 int ret;
10733
10734 vos_ssr_protect(__func__);
10735 ret = __wlan_hdd_cfg80211_scan(wiphy,
10736#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10737 dev,
10738#endif
10739 request);
10740 vos_ssr_unprotect(__func__);
10741
10742 return ret;
10743}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010744
10745void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
10746{
10747 v_U8_t iniDot11Mode =
10748 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
10749 eHddDot11Mode hddDot11Mode = iniDot11Mode;
10750
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010751 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
10752 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010753 switch ( iniDot11Mode )
10754 {
10755 case eHDD_DOT11_MODE_AUTO:
10756 case eHDD_DOT11_MODE_11ac:
10757 case eHDD_DOT11_MODE_11ac_ONLY:
10758#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053010759 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
10760 sme_IsFeatureSupportedByFW(DOT11AC) )
10761 hddDot11Mode = eHDD_DOT11_MODE_11ac;
10762 else
10763 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010764#else
10765 hddDot11Mode = eHDD_DOT11_MODE_11n;
10766#endif
10767 break;
10768 case eHDD_DOT11_MODE_11n:
10769 case eHDD_DOT11_MODE_11n_ONLY:
10770 hddDot11Mode = eHDD_DOT11_MODE_11n;
10771 break;
10772 default:
10773 hddDot11Mode = iniDot11Mode;
10774 break;
10775 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010776#ifdef WLAN_FEATURE_AP_HT40_24G
10777 if (operationChannel > SIR_11B_CHANNEL_END)
10778#endif
10779 {
10780 /* This call decides required channel bonding mode */
10781 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010782 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
10783 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010784 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010785}
10786
Jeff Johnson295189b2012-06-20 16:38:30 -070010787/*
10788 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010789 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010790 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010791int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010792 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010793{
10794 int status = 0;
10795 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080010796 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010797 v_U32_t roamId;
10798 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070010799 eCsrAuthType RSNAuthType;
10800
10801 ENTER();
10802
10803 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080010804 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10805
10806 status = wlan_hdd_validate_context(pHddCtx);
10807 if (status)
10808 {
Yue Mae36e3552014-03-05 17:06:20 -080010809 return status;
10810 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010811
Jeff Johnson295189b2012-06-20 16:38:30 -070010812 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
10813 {
10814 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
10815 return -EINVAL;
10816 }
10817
10818 pRoamProfile = &pWextState->roamProfile;
10819
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010820 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070010821 {
Jeff Johnsone7245742012-09-05 17:12:55 -070010822 hdd_station_ctx_t *pHddStaCtx;
10823 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010824
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010825 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070010826 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
10827 {
10828 /*QoS not enabled in cfg file*/
10829 pRoamProfile->uapsd_mask = 0;
10830 }
10831 else
10832 {
10833 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010834 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070010835 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
10836 }
10837
10838 pRoamProfile->SSIDs.numOfSSIDs = 1;
10839 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
10840 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010841 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070010842 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
10843 ssid, ssid_len);
10844
10845 if (bssid)
10846 {
10847 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
10848 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
10849 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010850 /* Save BSSID in seperate variable as well, as RoamProfile
10851 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070010852 case of join failure we should send valid BSSID to supplicant
10853 */
10854 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
10855 WNI_CFG_BSSID_LEN);
10856 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070010857 else
10858 {
10859 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
10860 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010861
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010862 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
10863 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010864 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
10865 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010866 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010867 /*set gen ie*/
10868 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
10869 /*set auth*/
10870 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
10871 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010872#ifdef FEATURE_WLAN_WAPI
10873 if (pAdapter->wapi_info.nWapiMode)
10874 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010875 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010876 switch (pAdapter->wapi_info.wapiAuthMode)
10877 {
10878 case WAPI_AUTH_MODE_PSK:
10879 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010880 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010881 pAdapter->wapi_info.wapiAuthMode);
10882 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
10883 break;
10884 }
10885 case WAPI_AUTH_MODE_CERT:
10886 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010887 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010888 pAdapter->wapi_info.wapiAuthMode);
10889 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
10890 break;
10891 }
10892 } // End of switch
10893 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
10894 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
10895 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010896 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010897 pRoamProfile->AuthType.numEntries = 1;
10898 pRoamProfile->EncryptionType.numEntries = 1;
10899 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10900 pRoamProfile->mcEncryptionType.numEntries = 1;
10901 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10902 }
10903 }
10904#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010905#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010906 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010907 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10908 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
10909 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010910 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
10911 sizeof (tSirGtkOffloadParams));
10912 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010913 }
10914#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010915 pRoamProfile->csrPersona = pAdapter->device_mode;
10916
Jeff Johnson32d95a32012-09-10 13:15:23 -070010917 if( operatingChannel )
10918 {
10919 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
10920 pRoamProfile->ChannelInfo.numOfChannels = 1;
10921 }
Chet Lanctot186b5732013-03-18 10:26:30 -070010922 else
10923 {
10924 pRoamProfile->ChannelInfo.ChannelList = NULL;
10925 pRoamProfile->ChannelInfo.numOfChannels = 0;
10926 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010927 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
10928 {
10929 hdd_select_cbmode(pAdapter,operatingChannel);
10930 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010931
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010932 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
10933 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010934 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010935 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010936 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
10937 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010938 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10939 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053010940 {
10941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10942 "%s: Set HDD connState to eConnectionState_Connecting",
10943 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010944 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
10945 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053010946 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010947 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010948 pAdapter->sessionId, pRoamProfile, &roamId);
10949
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010950 if ((eHAL_STATUS_SUCCESS != status) &&
10951 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10952 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010953
10954 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010955 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
10956 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
10957 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010958 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010959 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010960 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010961
10962 pRoamProfile->ChannelInfo.ChannelList = NULL;
10963 pRoamProfile->ChannelInfo.numOfChannels = 0;
10964
Jeff Johnson295189b2012-06-20 16:38:30 -070010965 }
10966 else
10967 {
10968 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
10969 return -EINVAL;
10970 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010971 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010972 return status;
10973}
10974
10975/*
10976 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
10977 * This function is used to set the authentication type (OPEN/SHARED).
10978 *
10979 */
10980static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
10981 enum nl80211_auth_type auth_type)
10982{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010983 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010984 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10985
10986 ENTER();
10987
10988 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010989 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070010990 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010991 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010992 hddLog(VOS_TRACE_LEVEL_INFO,
10993 "%s: set authentication type to AUTOSWITCH", __func__);
10994 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
10995 break;
10996
10997 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010998#ifdef WLAN_FEATURE_VOWIFI_11R
10999 case NL80211_AUTHTYPE_FT:
11000#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011001 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011002 "%s: set authentication type to OPEN", __func__);
11003 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11004 break;
11005
11006 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011007 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011008 "%s: set authentication type to SHARED", __func__);
11009 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
11010 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011011#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011012 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011013 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011014 "%s: set authentication type to CCKM WPA", __func__);
11015 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
11016 break;
11017#endif
11018
11019
11020 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011021 hddLog(VOS_TRACE_LEVEL_ERROR,
11022 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011023 auth_type);
11024 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
11025 return -EINVAL;
11026 }
11027
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011028 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011029 pHddStaCtx->conn_info.authType;
11030 return 0;
11031}
11032
11033/*
11034 * FUNCTION: wlan_hdd_set_akm_suite
11035 * This function is used to set the key mgmt type(PSK/8021x).
11036 *
11037 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011038static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011039 u32 key_mgmt
11040 )
11041{
11042 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11043 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053011044 /* Should be in ieee802_11_defs.h */
11045#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
11046#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070011047 /*set key mgmt type*/
11048 switch(key_mgmt)
11049 {
11050 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053011051 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011052#ifdef WLAN_FEATURE_VOWIFI_11R
11053 case WLAN_AKM_SUITE_FT_PSK:
11054#endif
11055 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070011056 __func__);
11057 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
11058 break;
11059
11060 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053011061 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011062#ifdef WLAN_FEATURE_VOWIFI_11R
11063 case WLAN_AKM_SUITE_FT_8021X:
11064#endif
11065 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070011066 __func__);
11067 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11068 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011069#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011070#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
11071#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
11072 case WLAN_AKM_SUITE_CCKM:
11073 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
11074 __func__);
11075 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
11076 break;
11077#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070011078#ifndef WLAN_AKM_SUITE_OSEN
11079#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
11080 case WLAN_AKM_SUITE_OSEN:
11081 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
11082 __func__);
11083 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11084 break;
11085#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011086
11087 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011088 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011089 __func__, key_mgmt);
11090 return -EINVAL;
11091
11092 }
11093 return 0;
11094}
11095
11096/*
11097 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011098 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070011099 * (NONE/WEP40/WEP104/TKIP/CCMP).
11100 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011101static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
11102 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070011103 bool ucast
11104 )
11105{
11106 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011107 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011108 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11109
11110 ENTER();
11111
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011112 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011113 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011114 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070011115 __func__, cipher);
11116 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11117 }
11118 else
11119 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011120
Jeff Johnson295189b2012-06-20 16:38:30 -070011121 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011122 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011123 {
11124 case IW_AUTH_CIPHER_NONE:
11125 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11126 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011127
Jeff Johnson295189b2012-06-20 16:38:30 -070011128 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011129 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070011130 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011131
Jeff Johnson295189b2012-06-20 16:38:30 -070011132 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011133 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070011134 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011135
Jeff Johnson295189b2012-06-20 16:38:30 -070011136 case WLAN_CIPHER_SUITE_TKIP:
11137 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
11138 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011139
Jeff Johnson295189b2012-06-20 16:38:30 -070011140 case WLAN_CIPHER_SUITE_CCMP:
11141 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11142 break;
11143#ifdef FEATURE_WLAN_WAPI
11144 case WLAN_CIPHER_SUITE_SMS4:
11145 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
11146 break;
11147#endif
11148
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011149#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011150 case WLAN_CIPHER_SUITE_KRK:
11151 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
11152 break;
11153#endif
11154 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011155 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011156 __func__, cipher);
11157 return -EOPNOTSUPP;
11158 }
11159 }
11160
11161 if (ucast)
11162 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011163 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011164 __func__, encryptionType);
11165 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11166 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011167 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011168 encryptionType;
11169 }
11170 else
11171 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011172 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011173 __func__, encryptionType);
11174 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
11175 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
11176 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
11177 }
11178
11179 return 0;
11180}
11181
11182
11183/*
11184 * FUNCTION: wlan_hdd_cfg80211_set_ie
11185 * This function is used to parse WPA/RSN IE's.
11186 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011187int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
11188 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070011189 size_t ie_len
11190 )
11191{
11192 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11193 u8 *genie = ie;
11194 v_U16_t remLen = ie_len;
11195#ifdef FEATURE_WLAN_WAPI
11196 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
11197 u16 *tmp;
11198 v_U16_t akmsuiteCount;
11199 int *akmlist;
11200#endif
11201 ENTER();
11202
11203 /* clear previous assocAddIE */
11204 pWextState->assocAddIE.length = 0;
11205 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011206 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011207
11208 while (remLen >= 2)
11209 {
11210 v_U16_t eLen = 0;
11211 v_U8_t elementId;
11212 elementId = *genie++;
11213 eLen = *genie++;
11214 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011215
Arif Hussain6d2a3322013-11-17 19:50:10 -080011216 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070011217 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011218
11219 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070011220 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011221 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011222 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 -070011223 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011224 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011225 "%s: Invalid WPA IE", __func__);
11226 return -EINVAL;
11227 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011228 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070011229 {
11230 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011231 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011232 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011233
Jeff Johnson295189b2012-06-20 16:38:30 -070011234 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11235 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011236 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
11237 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011238 VOS_ASSERT(0);
11239 return -ENOMEM;
11240 }
11241 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11242 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11243 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011244
Jeff Johnson295189b2012-06-20 16:38:30 -070011245 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
11246 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11247 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11248 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011249 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
11250 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011251 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
11252 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11253 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
11254 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
11255 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
11256 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011257 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053011258 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011259 {
11260 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011261 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011262 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011263
Jeff Johnson295189b2012-06-20 16:38:30 -070011264 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11265 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011266 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11267 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011268 VOS_ASSERT(0);
11269 return -ENOMEM;
11270 }
11271 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11272 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11273 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011274
Jeff Johnson295189b2012-06-20 16:38:30 -070011275 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11276 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11277 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011278#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011279 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
11280 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011281 /*Consider WFD IE, only for P2P Client */
11282 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11283 {
11284 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011285 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011286 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011287
Jeff Johnson295189b2012-06-20 16:38:30 -070011288 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11289 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011290 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11291 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011292 VOS_ASSERT(0);
11293 return -ENOMEM;
11294 }
11295 // WFD IE is saved to Additional IE ; it should be accumulated to handle
11296 // WPS IE + P2P IE + WFD IE
11297 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11298 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011299
Jeff Johnson295189b2012-06-20 16:38:30 -070011300 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11301 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11302 }
11303#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011304 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011305 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011306 HS20_OUI_TYPE_SIZE)) )
11307 {
11308 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011309 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011310 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011311
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011312 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11313 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011314 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11315 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011316 VOS_ASSERT(0);
11317 return -ENOMEM;
11318 }
11319 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11320 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011321
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011322 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11323 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11324 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011325 /* Appending OSEN Information Element in Assiciation Request */
11326 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
11327 OSEN_OUI_TYPE_SIZE)) )
11328 {
11329 v_U16_t curAddIELen = pWextState->assocAddIE.length;
11330 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
11331 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011332
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011333 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11334 {
11335 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11336 "Need bigger buffer space");
11337 VOS_ASSERT(0);
11338 return -ENOMEM;
11339 }
11340 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11341 pWextState->assocAddIE.length += eLen + 2;
11342
11343 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
11344 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11345 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11346 }
11347
11348 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011349 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
11350
11351 /* populating as ADDIE in beacon frames */
11352 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11353 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
11354 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
11355 {
11356 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11357 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
11358 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11359 {
11360 hddLog(LOGE,
11361 "Coldn't pass "
11362 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
11363 }
11364 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
11365 else
11366 hddLog(LOGE,
11367 "Could not pass on "
11368 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
11369
11370 /* IBSS mode doesn't contain params->proberesp_ies still
11371 beaconIE's need to be populated in probe response frames */
11372 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
11373 {
11374 u16 rem_probe_resp_ie_len = eLen + 2;
11375 u8 probe_rsp_ie_len[3] = {0};
11376 u8 counter = 0;
11377
11378 /* Check Probe Resp Length if it is greater then 255 then
11379 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
11380 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
11381 not able Store More then 255 bytes into One Variable */
11382
11383 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
11384 {
11385 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
11386 {
11387 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
11388 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
11389 }
11390 else
11391 {
11392 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
11393 rem_probe_resp_ie_len = 0;
11394 }
11395 }
11396
11397 rem_probe_resp_ie_len = 0;
11398
11399 if (probe_rsp_ie_len[0] > 0)
11400 {
11401 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11402 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
11403 (tANI_U8*)(genie - 2),
11404 probe_rsp_ie_len[0], NULL,
11405 eANI_BOOLEAN_FALSE)
11406 == eHAL_STATUS_FAILURE)
11407 {
11408 hddLog(LOGE,
11409 "Could not pass"
11410 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
11411 }
11412 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
11413 }
11414
11415 if (probe_rsp_ie_len[1] > 0)
11416 {
11417 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11418 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
11419 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11420 probe_rsp_ie_len[1], NULL,
11421 eANI_BOOLEAN_FALSE)
11422 == eHAL_STATUS_FAILURE)
11423 {
11424 hddLog(LOGE,
11425 "Could not pass"
11426 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
11427 }
11428 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
11429 }
11430
11431 if (probe_rsp_ie_len[2] > 0)
11432 {
11433 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11434 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
11435 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11436 probe_rsp_ie_len[2], NULL,
11437 eANI_BOOLEAN_FALSE)
11438 == eHAL_STATUS_FAILURE)
11439 {
11440 hddLog(LOGE,
11441 "Could not pass"
11442 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
11443 }
11444 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
11445 }
11446
11447 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11448 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
11449 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11450 {
11451 hddLog(LOGE,
11452 "Could not pass"
11453 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
11454 }
11455 }
11456 else
11457 {
11458 // Reset WNI_CFG_PROBE_RSP Flags
11459 wlan_hdd_reset_prob_rspies(pAdapter);
11460
11461 hddLog(VOS_TRACE_LEVEL_INFO,
11462 "%s: No Probe Response IE received in set beacon",
11463 __func__);
11464 }
11465 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011466 break;
11467 case DOT11F_EID_RSN:
11468 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11469 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11470 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11471 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11472 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11473 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011474 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
11475 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011476 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011477 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011478 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011479 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011480
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011481 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11482 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011483 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11484 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011485 VOS_ASSERT(0);
11486 return -ENOMEM;
11487 }
11488 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11489 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011490
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011491 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11492 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11493 break;
11494 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011495#ifdef FEATURE_WLAN_WAPI
11496 case WLAN_EID_WAPI:
11497 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011498 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011499 pAdapter->wapi_info.nWapiMode);
11500 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011501 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070011502 akmsuiteCount = WPA_GET_LE16(tmp);
11503 tmp = tmp + 1;
11504 akmlist = (int *)(tmp);
11505 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
11506 {
11507 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
11508 }
11509 else
11510 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011511 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070011512 VOS_ASSERT(0);
11513 return -EINVAL;
11514 }
11515
11516 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
11517 {
11518 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011519 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011520 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011521 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011522 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011523 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011524 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011525 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011526 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
11527 }
11528 break;
11529#endif
11530 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011531 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011532 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011533 /* when Unknown IE is received we should break and continue
11534 * to the next IE in the buffer instead we were returning
11535 * so changing this to break */
11536 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011537 }
11538 genie += eLen;
11539 remLen -= eLen;
11540 }
11541 EXIT();
11542 return 0;
11543}
11544
11545/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053011546 * FUNCTION: hdd_isWPAIEPresent
11547 * Parse the received IE to find the WPA IE
11548 *
11549 */
11550static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
11551{
11552 v_U8_t eLen = 0;
11553 v_U16_t remLen = ie_len;
11554 v_U8_t elementId = 0;
11555
11556 while (remLen >= 2)
11557 {
11558 elementId = *ie++;
11559 eLen = *ie++;
11560 remLen -= 2;
11561 if (eLen > remLen)
11562 {
11563 hddLog(VOS_TRACE_LEVEL_ERROR,
11564 "%s: IE length is wrong %d", __func__, eLen);
11565 return FALSE;
11566 }
11567 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
11568 {
11569 /* OUI - 0x00 0X50 0XF2
11570 WPA Information Element - 0x01
11571 WPA version - 0x01*/
11572 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
11573 return TRUE;
11574 }
11575 ie += eLen;
11576 remLen -= eLen;
11577 }
11578 return FALSE;
11579}
11580
11581/*
Jeff Johnson295189b2012-06-20 16:38:30 -070011582 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011583 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011584 * parameters during connect operation.
11585 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011586int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011587 struct cfg80211_connect_params *req
11588 )
11589{
11590 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011591 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011592 ENTER();
11593
11594 /*set wpa version*/
11595 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
11596
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011597 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011598 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053011599 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011600 {
11601 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11602 }
11603 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
11604 {
11605 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11606 }
11607 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011608
11609 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011610 pWextState->wpaVersion);
11611
11612 /*set authentication type*/
11613 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
11614
11615 if (0 > status)
11616 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011617 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011618 "%s: failed to set authentication type ", __func__);
11619 return status;
11620 }
11621
11622 /*set key mgmt type*/
11623 if (req->crypto.n_akm_suites)
11624 {
11625 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
11626 if (0 > status)
11627 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011628 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070011629 __func__);
11630 return status;
11631 }
11632 }
11633
11634 /*set pairwise cipher type*/
11635 if (req->crypto.n_ciphers_pairwise)
11636 {
11637 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
11638 req->crypto.ciphers_pairwise[0], true);
11639 if (0 > status)
11640 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011641 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011642 "%s: failed to set unicast cipher type", __func__);
11643 return status;
11644 }
11645 }
11646 else
11647 {
11648 /*Reset previous cipher suite to none*/
11649 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
11650 if (0 > status)
11651 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011652 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011653 "%s: failed to set unicast cipher type", __func__);
11654 return status;
11655 }
11656 }
11657
11658 /*set group cipher type*/
11659 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
11660 false);
11661
11662 if (0 > status)
11663 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011664 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070011665 __func__);
11666 return status;
11667 }
11668
Chet Lanctot186b5732013-03-18 10:26:30 -070011669#ifdef WLAN_FEATURE_11W
11670 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
11671#endif
11672
Jeff Johnson295189b2012-06-20 16:38:30 -070011673 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
11674 if (req->ie_len)
11675 {
11676 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
11677 if ( 0 > status)
11678 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011679 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011680 __func__);
11681 return status;
11682 }
11683 }
11684
11685 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011686 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011687 {
11688 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
11689 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
11690 )
11691 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011692 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070011693 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
11694 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011696 __func__);
11697 return -EOPNOTSUPP;
11698 }
11699 else
11700 {
11701 u8 key_len = req->key_len;
11702 u8 key_idx = req->key_idx;
11703
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011704 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011705 && (CSR_MAX_NUM_KEY > key_idx)
11706 )
11707 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011708 hddLog(VOS_TRACE_LEVEL_INFO,
11709 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011710 __func__, key_idx, key_len);
11711 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011712 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011713 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011714 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011715 (u8)key_len;
11716 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
11717 }
11718 }
11719 }
11720 }
11721
11722 return status;
11723}
11724
11725/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011726 * FUNCTION: wlan_hdd_try_disconnect
11727 * This function is used to disconnect from previous
11728 * connection
11729 */
11730static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
11731{
11732 long ret = 0;
11733 hdd_station_ctx_t *pHddStaCtx;
11734 eMib_dot11DesiredBssType connectedBssType;
11735
11736 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11737
11738 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
11739
11740 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
11741 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
11742 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
11743 {
11744 /* Issue disconnect to CSR */
11745 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11746 if( eHAL_STATUS_SUCCESS ==
11747 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11748 pAdapter->sessionId,
11749 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11750 {
11751 ret = wait_for_completion_interruptible_timeout(
11752 &pAdapter->disconnect_comp_var,
11753 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11754 if (0 >= ret)
11755 {
11756 hddLog(LOGE, FL("Failed to receive disconnect event"));
11757 return -EALREADY;
11758 }
11759 }
11760 }
11761 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
11762 {
11763 ret = wait_for_completion_interruptible_timeout(
11764 &pAdapter->disconnect_comp_var,
11765 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11766 if (0 >= ret)
11767 {
11768 hddLog(LOGE, FL("Failed to receive disconnect event"));
11769 return -EALREADY;
11770 }
11771 }
11772
11773 return 0;
11774}
11775
11776/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053011777 * FUNCTION: __wlan_hdd_cfg80211_connect
11778 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011779 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011780static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011781 struct net_device *ndev,
11782 struct cfg80211_connect_params *req
11783 )
11784{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011785 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011786 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011787 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053011788 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011789
11790 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011791
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011792 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11793 TRACE_CODE_HDD_CFG80211_CONNECT,
11794 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011795 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011796 "%s: device_mode = %s (%d)", __func__,
11797 hdd_device_modetoString(pAdapter->device_mode),
11798 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011799
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011800 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011801 if (!pHddCtx)
11802 {
11803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11804 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011805 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011806 }
11807
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011808 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011809 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011810 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011811 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011812 }
11813
Agarwal Ashish51325b52014-06-16 16:50:49 +053011814 if (vos_max_concurrent_connections_reached()) {
11815 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11816 return -ECONNREFUSED;
11817 }
11818
Jeff Johnson295189b2012-06-20 16:38:30 -070011819#ifdef WLAN_BTAMP_FEATURE
11820 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011821 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070011822 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011823 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011824 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011825 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070011826 }
11827#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011828
11829 //If Device Mode is Station Concurrent Sessions Exit BMps
11830 //P2P Mode will be taken care in Open/close adapter
11831 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011832 (vos_concurrent_open_sessions_running())) {
11833 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
11834 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011835 }
11836
11837 /*Try disconnecting if already in connected state*/
11838 status = wlan_hdd_try_disconnect(pAdapter);
11839 if ( 0 > status)
11840 {
11841 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11842 " connection"));
11843 return -EALREADY;
11844 }
11845
Jeff Johnson295189b2012-06-20 16:38:30 -070011846 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011847 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070011848
11849 if ( 0 > status)
11850 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011851 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070011852 __func__);
11853 return status;
11854 }
Mohit Khanna765234a2012-09-11 15:08:35 -070011855 if ( req->channel )
11856 {
11857 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
11858 req->ssid_len, req->bssid,
11859 req->channel->hw_value);
11860 }
11861 else
11862 {
11863 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011864 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070011865 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011866
11867 if (0 > status)
11868 {
11869 //ReEnable BMPS if disabled
11870 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
11871 (NULL != pHddCtx))
11872 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011873 if (pHddCtx->hdd_wlan_suspended)
11874 {
11875 hdd_set_pwrparams(pHddCtx);
11876 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011877 //ReEnable Bmps and Imps back
11878 hdd_enable_bmps_imps(pHddCtx);
11879 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011880 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011881 return status;
11882 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011883 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011884 EXIT();
11885 return status;
11886}
11887
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011888static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
11889 struct net_device *ndev,
11890 struct cfg80211_connect_params *req)
11891{
11892 int ret;
11893 vos_ssr_protect(__func__);
11894 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
11895 vos_ssr_unprotect(__func__);
11896
11897 return ret;
11898}
Jeff Johnson295189b2012-06-20 16:38:30 -070011899
11900/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011901 * FUNCTION: wlan_hdd_disconnect
11902 * This function is used to issue a disconnect request to SME
11903 */
11904int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
11905{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011906 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011907 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011908 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011909 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011910
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011911 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011912
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011913 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011914 if (0 != status)
11915 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011916 return status;
11917 }
11918
11919 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011920
Agarwal Ashish47d18112014-08-04 19:55:07 +053011921 /* Need to apply spin lock before decreasing active sessions
11922 * as there can be chance for double decrement if context switch
11923 * Calls hdd_DisConnectHandler.
11924 */
11925
11926 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011927 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11928 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011929 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11930 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053011931 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
11932 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011933
Abhishek Singhf4669da2014-05-26 15:07:49 +053011934 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053011935 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
11936
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011937 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011938
Mihir Shete182a0b22014-08-18 16:08:48 +053011939 /*
11940 * stop tx queues before deleting STA/BSS context from the firmware.
11941 * tx has to be disabled because the firmware can get busy dropping
11942 * the tx frames after BSS/STA has been deleted and will not send
11943 * back a response resulting in WDI timeout
11944 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053011945 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053011946 netif_tx_disable(pAdapter->dev);
11947 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011948
Mihir Shete182a0b22014-08-18 16:08:48 +053011949 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011950 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11951 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011952 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
11953 {
11954 hddLog(VOS_TRACE_LEVEL_INFO,
11955 FL("status = %d, already disconnected"),
11956 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011957
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011958 }
11959 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011960 {
11961 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011962 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011963 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011964 result = -EINVAL;
11965 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011966 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011967 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011968 &pAdapter->disconnect_comp_var,
11969 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011970 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011971 {
11972 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011973 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011974 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011975 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011976 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011977 {
11978 hddLog(VOS_TRACE_LEVEL_ERROR,
11979 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011980 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011981 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011982disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011983 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11984 FL("Set HDD connState to eConnectionState_NotConnected"));
11985 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
11986
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011987 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011988 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011989}
11990
11991
11992/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011993 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070011994 * This function is used to issue a disconnect request to SME
11995 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011996static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011997 struct net_device *dev,
11998 u16 reason
11999 )
12000{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012001 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012002 tCsrRoamProfile *pRoamProfile =
12003 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012004 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012005 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12006 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012007#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012008 tANI_U8 staIdx;
12009#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012010
Jeff Johnson295189b2012-06-20 16:38:30 -070012011 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012012
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012013 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12014 TRACE_CODE_HDD_CFG80211_DISCONNECT,
12015 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012016 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
12017 __func__, hdd_device_modetoString(pAdapter->device_mode),
12018 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012019
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012020 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
12021 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070012022
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012023 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012024 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012025 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012026 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012027 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012028
Jeff Johnson295189b2012-06-20 16:38:30 -070012029 if (NULL != pRoamProfile)
12030 {
12031 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012032 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
12033 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070012034 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012035 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070012036 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012037 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012038 switch(reason)
12039 {
12040 case WLAN_REASON_MIC_FAILURE:
12041 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
12042 break;
12043
12044 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
12045 case WLAN_REASON_DISASSOC_AP_BUSY:
12046 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
12047 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
12048 break;
12049
12050 case WLAN_REASON_PREV_AUTH_NOT_VALID:
12051 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053012052 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070012053 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
12054 break;
12055
Jeff Johnson295189b2012-06-20 16:38:30 -070012056 default:
12057 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
12058 break;
12059 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012060 pScanInfo = &pHddCtx->scan_info;
12061 if (pScanInfo->mScanPending)
12062 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012063 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012064 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012065 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012066 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012067 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012068
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012069#ifdef FEATURE_WLAN_TDLS
12070 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012071 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012072 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012073 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
12074 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012075 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012076 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012077 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012078 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012079 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012080 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012081 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012082 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012083 pAdapter->sessionId,
12084 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012085 }
12086 }
12087#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012088 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012089 status = wlan_hdd_disconnect(pAdapter, reasonCode);
12090 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070012091 {
12092 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012093 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012094 __func__, (int)status );
12095 return -EINVAL;
12096 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012097 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012098 else
12099 {
12100 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
12101 "called while in %d state", __func__,
12102 pHddStaCtx->conn_info.connState);
12103 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012104 }
12105 else
12106 {
12107 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
12108 }
12109
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012110 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012111 return status;
12112}
12113
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012114static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
12115 struct net_device *dev,
12116 u16 reason
12117 )
12118{
12119 int ret;
12120 vos_ssr_protect(__func__);
12121 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
12122 vos_ssr_unprotect(__func__);
12123
12124 return ret;
12125}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012126
Jeff Johnson295189b2012-06-20 16:38:30 -070012127/*
12128 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012129 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012130 * settings in IBSS mode.
12131 */
12132static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012133 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012134 struct cfg80211_ibss_params *params
12135 )
12136{
12137 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012138 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012139 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12140 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012141
Jeff Johnson295189b2012-06-20 16:38:30 -070012142 ENTER();
12143
12144 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070012145 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070012146
12147 if (params->ie_len && ( NULL != params->ie) )
12148 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012149 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12150 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012151 {
12152 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12153 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12154 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012155 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012156 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012157 tDot11fIEWPA dot11WPAIE;
12158 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012159 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012160
Wilson Yang00256342013-10-10 23:13:38 -070012161 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012162 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12163 params->ie_len, DOT11F_EID_WPA);
12164 if ( NULL != ie )
12165 {
12166 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12167 // Unpack the WPA IE
12168 //Skip past the EID byte and length byte - and four byte WiFi OUI
12169 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
12170 &ie[2+4],
12171 ie[1] - 4,
12172 &dot11WPAIE);
12173 /*Extract the multicast cipher, the encType for unicast
12174 cipher for wpa-none is none*/
12175 encryptionType =
12176 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
12177 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012178 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012179
Jeff Johnson295189b2012-06-20 16:38:30 -070012180 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
12181
12182 if (0 > status)
12183 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012184 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012185 __func__);
12186 return status;
12187 }
12188 }
12189
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012190 pWextState->roamProfile.AuthType.authType[0] =
12191 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012192 eCSR_AUTH_TYPE_OPEN_SYSTEM;
12193
12194 if (params->privacy)
12195 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012196 /* Security enabled IBSS, At this time there is no information available
12197 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070012198 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012199 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070012200 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012201 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070012202 *enable privacy bit in beacons */
12203
12204 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12205 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012206 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
12207 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070012208 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12209 pWextState->roamProfile.EncryptionType.numEntries = 1;
12210 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070012211 return status;
12212}
12213
12214/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012215 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012216 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012217 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012218static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012219 struct net_device *dev,
12220 struct cfg80211_ibss_params *params
12221 )
12222{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012223 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012224 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12225 tCsrRoamProfile *pRoamProfile;
12226 int status;
krunal sonie9002db2013-11-25 14:24:17 -080012227 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012228 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12229 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012230
12231 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012232
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012233 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12234 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
12235 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012236 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012237 "%s: device_mode = %s (%d)", __func__,
12238 hdd_device_modetoString(pAdapter->device_mode),
12239 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012240
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012241 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012242 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012243 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012244 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012245 }
12246
12247 if (NULL == pWextState)
12248 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012249 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012250 __func__);
12251 return -EIO;
12252 }
12253
Agarwal Ashish51325b52014-06-16 16:50:49 +053012254 if (vos_max_concurrent_connections_reached()) {
12255 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12256 return -ECONNREFUSED;
12257 }
12258
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012259 /*Try disconnecting if already in connected state*/
12260 status = wlan_hdd_try_disconnect(pAdapter);
12261 if ( 0 > status)
12262 {
12263 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12264 " IBSS connection"));
12265 return -EALREADY;
12266 }
12267
Jeff Johnson295189b2012-06-20 16:38:30 -070012268 pRoamProfile = &pWextState->roamProfile;
12269
12270 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
12271 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012272 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012273 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012274 return -EINVAL;
12275 }
12276
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012277 /* BSSID is provided by upper layers hence no need to AUTO generate */
12278 if (NULL != params->bssid) {
12279 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12280 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
12281 hddLog (VOS_TRACE_LEVEL_ERROR,
12282 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12283 return -EIO;
12284 }
12285 }
krunal sonie9002db2013-11-25 14:24:17 -080012286 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
12287 {
12288 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12289 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
12290 {
12291 hddLog (VOS_TRACE_LEVEL_ERROR,
12292 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12293 return -EIO;
12294 }
12295 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
12296 if (!params->bssid)
12297 {
12298 hddLog (VOS_TRACE_LEVEL_ERROR,
12299 "%s:Failed memory allocation", __func__);
12300 return -EIO;
12301 }
12302 vos_mem_copy((v_U8_t *)params->bssid,
12303 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
12304 VOS_MAC_ADDR_SIZE);
12305 alloc_bssid = VOS_TRUE;
12306 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012307
Jeff Johnson295189b2012-06-20 16:38:30 -070012308 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070012309 if (NULL !=
12310#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12311 params->chandef.chan)
12312#else
12313 params->channel)
12314#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012315 {
12316 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012317 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12318 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
12319 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12320 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012321
12322 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012323 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070012324 ieee80211_frequency_to_channel(
12325#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12326 params->chandef.chan->center_freq);
12327#else
12328 params->channel->center_freq);
12329#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012330
12331 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12332 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070012333 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012334 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
12335 __func__);
12336 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012337 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012338
12339 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012340 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012341 if (channelNum == validChan[indx])
12342 {
12343 break;
12344 }
12345 }
12346 if (indx >= numChans)
12347 {
12348 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012349 __func__, channelNum);
12350 return -EINVAL;
12351 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012352 /* Set the Operational Channel */
12353 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
12354 channelNum);
12355 pRoamProfile->ChannelInfo.numOfChannels = 1;
12356 pHddStaCtx->conn_info.operationChannel = channelNum;
12357 pRoamProfile->ChannelInfo.ChannelList =
12358 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070012359 }
12360
12361 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012362 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070012363 if (status < 0)
12364 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012365 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070012366 __func__);
12367 return status;
12368 }
12369
12370 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012371 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012372 params->ssid_len, params->bssid,
12373 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012374
12375 if (0 > status)
12376 {
12377 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
12378 return status;
12379 }
12380
krunal sonie9002db2013-11-25 14:24:17 -080012381 if (NULL != params->bssid &&
12382 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
12383 alloc_bssid == VOS_TRUE)
12384 {
12385 vos_mem_free(params->bssid);
12386 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012387 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012388 return 0;
12389}
12390
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012391static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
12392 struct net_device *dev,
12393 struct cfg80211_ibss_params *params
12394 )
12395{
12396 int ret = 0;
12397
12398 vos_ssr_protect(__func__);
12399 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
12400 vos_ssr_unprotect(__func__);
12401
12402 return ret;
12403}
12404
Jeff Johnson295189b2012-06-20 16:38:30 -070012405/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012406 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012407 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012408 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012409static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012410 struct net_device *dev
12411 )
12412{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012413 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012414 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12415 tCsrRoamProfile *pRoamProfile;
12416 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012417 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012418
12419 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012420
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012421 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12422 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
12423 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012424 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012425 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012426 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012427 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012428 }
12429
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012430 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
12431 hdd_device_modetoString(pAdapter->device_mode),
12432 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012433 if (NULL == pWextState)
12434 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012435 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012436 __func__);
12437 return -EIO;
12438 }
12439
12440 pRoamProfile = &pWextState->roamProfile;
12441
12442 /* Issue disconnect only if interface type is set to IBSS */
12443 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
12444 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012445 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012446 __func__);
12447 return -EINVAL;
12448 }
12449
12450 /* Issue Disconnect request */
12451 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12452 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12453 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12454
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012455 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012456 return 0;
12457}
12458
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012459static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12460 struct net_device *dev
12461 )
12462{
12463 int ret = 0;
12464
12465 vos_ssr_protect(__func__);
12466 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12467 vos_ssr_unprotect(__func__);
12468
12469 return ret;
12470}
12471
Jeff Johnson295189b2012-06-20 16:38:30 -070012472/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012473 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012474 * This function is used to set the phy parameters
12475 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12476 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012477static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012478 u32 changed)
12479{
12480 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12481 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012482 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012483
12484 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012485
12486 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012487 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
12488 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012489
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012490 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012491 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012492 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012493 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012494 }
12495
Jeff Johnson295189b2012-06-20 16:38:30 -070012496 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
12497 {
12498 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
12499 WNI_CFG_RTS_THRESHOLD_STAMAX :
12500 wiphy->rts_threshold;
12501
12502 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012503 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070012504 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012505 hddLog(VOS_TRACE_LEVEL_ERROR,
12506 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012507 __func__, rts_threshold);
12508 return -EINVAL;
12509 }
12510
12511 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
12512 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012513 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012514 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012515 hddLog(VOS_TRACE_LEVEL_ERROR,
12516 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012517 __func__, rts_threshold);
12518 return -EIO;
12519 }
12520
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012521 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012522 rts_threshold);
12523 }
12524
12525 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
12526 {
12527 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
12528 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
12529 wiphy->frag_threshold;
12530
12531 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012532 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012533 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012534 hddLog(VOS_TRACE_LEVEL_ERROR,
12535 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012536 frag_threshold);
12537 return -EINVAL;
12538 }
12539
12540 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
12541 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012542 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012543 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012544 hddLog(VOS_TRACE_LEVEL_ERROR,
12545 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012546 __func__, frag_threshold);
12547 return -EIO;
12548 }
12549
12550 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
12551 frag_threshold);
12552 }
12553
12554 if ((changed & WIPHY_PARAM_RETRY_SHORT)
12555 || (changed & WIPHY_PARAM_RETRY_LONG))
12556 {
12557 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
12558 wiphy->retry_short :
12559 wiphy->retry_long;
12560
12561 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
12562 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
12563 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012564 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012565 __func__, retry_value);
12566 return -EINVAL;
12567 }
12568
12569 if (changed & WIPHY_PARAM_RETRY_SHORT)
12570 {
12571 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
12572 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012573 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012574 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012575 hddLog(VOS_TRACE_LEVEL_ERROR,
12576 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012577 __func__, retry_value);
12578 return -EIO;
12579 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012580 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012581 __func__, retry_value);
12582 }
12583 else if (changed & WIPHY_PARAM_RETRY_SHORT)
12584 {
12585 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
12586 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012587 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012588 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012589 hddLog(VOS_TRACE_LEVEL_ERROR,
12590 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012591 __func__, retry_value);
12592 return -EIO;
12593 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012594 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012595 __func__, retry_value);
12596 }
12597 }
12598
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012599 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012600 return 0;
12601}
12602
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012603static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
12604 u32 changed)
12605{
12606 int ret;
12607
12608 vos_ssr_protect(__func__);
12609 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
12610 vos_ssr_unprotect(__func__);
12611
12612 return ret;
12613}
12614
Jeff Johnson295189b2012-06-20 16:38:30 -070012615/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012616 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012617 * This function is used to set the txpower
12618 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012619static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012620#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12621 struct wireless_dev *wdev,
12622#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012623#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012624 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012625#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012626 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012627#endif
12628 int dbm)
12629{
12630 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012631 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012632 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12633 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012634 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012635
12636 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012637
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012638 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12639 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
12640 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012641 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012642 if (0 != status)
12643 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012644 return status;
12645 }
12646
12647 hHal = pHddCtx->hHal;
12648
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012649 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
12650 dbm, ccmCfgSetCallback,
12651 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012652 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012653 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012654 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
12655 return -EIO;
12656 }
12657
12658 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
12659 dbm);
12660
12661 switch(type)
12662 {
12663 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
12664 /* Fall through */
12665 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
12666 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
12667 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012668 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
12669 __func__);
12670 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012671 }
12672 break;
12673 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012674 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012675 __func__);
12676 return -EOPNOTSUPP;
12677 break;
12678 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012679 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
12680 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070012681 return -EIO;
12682 }
12683
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012684 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012685 return 0;
12686}
12687
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012688static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
12689#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12690 struct wireless_dev *wdev,
12691#endif
12692#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12693 enum tx_power_setting type,
12694#else
12695 enum nl80211_tx_power_setting type,
12696#endif
12697 int dbm)
12698{
12699 int ret;
12700 vos_ssr_protect(__func__);
12701 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
12702#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12703 wdev,
12704#endif
12705#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12706 type,
12707#else
12708 type,
12709#endif
12710 dbm);
12711 vos_ssr_unprotect(__func__);
12712
12713 return ret;
12714}
12715
Jeff Johnson295189b2012-06-20 16:38:30 -070012716/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012717 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012718 * This function is used to read the txpower
12719 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012720static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012721#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12722 struct wireless_dev *wdev,
12723#endif
12724 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070012725{
12726
12727 hdd_adapter_t *pAdapter;
12728 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012729 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012730
Jeff Johnsone7245742012-09-05 17:12:55 -070012731 ENTER();
12732
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012733 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012734 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012735 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012736 *dbm = 0;
12737 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012738 }
12739
Jeff Johnson295189b2012-06-20 16:38:30 -070012740 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
12741 if (NULL == pAdapter)
12742 {
12743 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
12744 return -ENOENT;
12745 }
12746
12747 wlan_hdd_get_classAstats(pAdapter);
12748 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
12749
Jeff Johnsone7245742012-09-05 17:12:55 -070012750 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012751 return 0;
12752}
12753
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012754static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
12755#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12756 struct wireless_dev *wdev,
12757#endif
12758 int *dbm)
12759{
12760 int ret;
12761
12762 vos_ssr_protect(__func__);
12763 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
12764#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12765 wdev,
12766#endif
12767 dbm);
12768 vos_ssr_unprotect(__func__);
12769
12770 return ret;
12771}
12772
12773
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012774static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070012775 u8* mac, struct station_info *sinfo)
12776{
12777 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12778 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12779 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053012780 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070012781
12782 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
12783 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012784
12785 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
12786 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
12787 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
12788 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
12789 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
12790 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
12791 tANI_U16 maxRate = 0;
12792 tANI_U16 myRate;
12793 tANI_U16 currentRate = 0;
12794 tANI_U8 maxSpeedMCS = 0;
12795 tANI_U8 maxMCSIdx = 0;
12796 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053012797 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012798 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012799 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012800
Leo Chang6f8870f2013-03-26 18:11:36 -070012801#ifdef WLAN_FEATURE_11AC
12802 tANI_U32 vht_mcs_map;
12803 eDataRate11ACMaxMcs vhtMaxMcs;
12804#endif /* WLAN_FEATURE_11AC */
12805
Jeff Johnsone7245742012-09-05 17:12:55 -070012806 ENTER();
12807
Jeff Johnson295189b2012-06-20 16:38:30 -070012808 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
12809 (0 == ssidlen))
12810 {
12811 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
12812 " Invalid ssidlen, %d", __func__, ssidlen);
12813 /*To keep GUI happy*/
12814 return 0;
12815 }
12816
Mukul Sharma811205f2014-07-09 21:07:30 +053012817 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
12818 {
12819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12820 "%s: Roaming in progress, so unable to proceed this request", __func__);
12821 return 0;
12822 }
12823
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012824 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012825 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012826 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012827 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012828 }
12829
Jeff Johnson295189b2012-06-20 16:38:30 -070012830
Kiet Lam3b17fc82013-09-27 05:24:08 +053012831 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
12832 sinfo->filled |= STATION_INFO_SIGNAL;
12833
c_hpothu09f19542014-05-30 21:53:31 +053012834 wlan_hdd_get_station_stats(pAdapter);
12835 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
12836
12837 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053012838 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
12839 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053012840 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053012841 {
12842 rate_flags = pAdapter->maxRateFlags;
12843 }
c_hpothu44ff4e02014-05-08 00:13:57 +053012844
Jeff Johnson295189b2012-06-20 16:38:30 -070012845 //convert to the UI units of 100kbps
12846 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
12847
12848#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070012849 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 -070012850 sinfo->signal,
12851 pCfg->reportMaxLinkSpeed,
12852 myRate,
12853 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012854 (int) pCfg->linkSpeedRssiMid,
12855 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070012856 (int) rate_flags,
12857 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012858#endif //LINKSPEED_DEBUG_ENABLED
12859
12860 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
12861 {
12862 // we do not want to necessarily report the current speed
12863 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
12864 {
12865 // report the max possible speed
12866 rssidx = 0;
12867 }
12868 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
12869 {
12870 // report the max possible speed with RSSI scaling
12871 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
12872 {
12873 // report the max possible speed
12874 rssidx = 0;
12875 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012876 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070012877 {
12878 // report middle speed
12879 rssidx = 1;
12880 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012881 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
12882 {
12883 // report middle speed
12884 rssidx = 2;
12885 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012886 else
12887 {
12888 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012889 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070012890 }
12891 }
12892 else
12893 {
12894 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
12895 hddLog(VOS_TRACE_LEVEL_ERROR,
12896 "%s: Invalid value for reportMaxLinkSpeed: %u",
12897 __func__, pCfg->reportMaxLinkSpeed);
12898 rssidx = 0;
12899 }
12900
12901 maxRate = 0;
12902
12903 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012904 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
12905 OperationalRates, &ORLeng))
12906 {
12907 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12908 /*To keep GUI happy*/
12909 return 0;
12910 }
12911
Jeff Johnson295189b2012-06-20 16:38:30 -070012912 for (i = 0; i < ORLeng; i++)
12913 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012914 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012915 {
12916 /* Validate Rate Set */
12917 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
12918 {
12919 currentRate = supported_data_rate[j].supported_rate[rssidx];
12920 break;
12921 }
12922 }
12923 /* Update MAX rate */
12924 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12925 }
12926
12927 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012928 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
12929 ExtendedRates, &ERLeng))
12930 {
12931 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12932 /*To keep GUI happy*/
12933 return 0;
12934 }
12935
Jeff Johnson295189b2012-06-20 16:38:30 -070012936 for (i = 0; i < ERLeng; i++)
12937 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012938 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012939 {
12940 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
12941 {
12942 currentRate = supported_data_rate[j].supported_rate[rssidx];
12943 break;
12944 }
12945 }
12946 /* Update MAX rate */
12947 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12948 }
c_hpothu79aab322014-07-14 21:11:01 +053012949
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012950 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053012951 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012952 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053012953 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070012954 {
c_hpothu79aab322014-07-14 21:11:01 +053012955 if (rate_flags & eHAL_TX_RATE_VHT80)
12956 mode = 2;
12957 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
12958 mode = 1;
12959 else
12960 mode = 0;
12961
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012962 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
12963 MCSRates, &MCSLeng))
12964 {
12965 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12966 /*To keep GUI happy*/
12967 return 0;
12968 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012969 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070012970#ifdef WLAN_FEATURE_11AC
12971 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012972 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070012973 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012974 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012975 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070012976 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070012977 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012978 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070012979 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012980 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070012981 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012982 maxMCSIdx = 7;
12983 }
12984 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
12985 {
12986 maxMCSIdx = 8;
12987 }
12988 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
12989 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012990 //VHT20 is supporting 0~8
12991 if (rate_flags & eHAL_TX_RATE_VHT20)
12992 maxMCSIdx = 8;
12993 else
12994 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070012995 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012996
c_hpothu79aab322014-07-14 21:11:01 +053012997 if (0 != rssidx)/*check for scaled */
12998 {
12999 //get middle rate MCS index if rssi=1/2
13000 for (i=0; i <= maxMCSIdx; i++)
13001 {
13002 if (sinfo->signal <= rssiMcsTbl[mode][i])
13003 {
13004 maxMCSIdx = i;
13005 break;
13006 }
13007 }
13008 }
13009
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013010 if (rate_flags & eHAL_TX_RATE_VHT80)
13011 {
13012 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
13013 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
13014 }
13015 else if (rate_flags & eHAL_TX_RATE_VHT40)
13016 {
13017 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
13018 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
13019 }
13020 else if (rate_flags & eHAL_TX_RATE_VHT20)
13021 {
13022 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
13023 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
13024 }
13025
Leo Chang6f8870f2013-03-26 18:11:36 -070013026 maxSpeedMCS = 1;
13027 if (currentRate > maxRate)
13028 {
13029 maxRate = currentRate;
13030 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013031
Leo Chang6f8870f2013-03-26 18:11:36 -070013032 }
13033 else
13034#endif /* WLAN_FEATURE_11AC */
13035 {
13036 if (rate_flags & eHAL_TX_RATE_HT40)
13037 {
13038 rateFlag |= 1;
13039 }
13040 if (rate_flags & eHAL_TX_RATE_SGI)
13041 {
13042 rateFlag |= 2;
13043 }
13044
Girish Gowli01abcee2014-07-31 20:18:55 +053013045 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053013046 if (rssidx == 1 || rssidx == 2)
13047 {
13048 //get middle rate MCS index if rssi=1/2
13049 for (i=0; i <= 7; i++)
13050 {
13051 if (sinfo->signal <= rssiMcsTbl[mode][i])
13052 {
13053 temp = i+1;
13054 break;
13055 }
13056 }
13057 }
c_hpothu79aab322014-07-14 21:11:01 +053013058
13059 for (i = 0; i < MCSLeng; i++)
13060 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013061 for (j = 0; j < temp; j++)
13062 {
13063 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
13064 {
13065 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
13066 break;
13067 }
13068 }
13069 if ((j < temp) && (currentRate > maxRate))
13070 {
13071 maxRate = currentRate;
13072 maxSpeedMCS = 1;
13073 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
13074 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013075 }
13076 }
13077 }
13078
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013079 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
13080 {
13081 maxRate = myRate;
13082 maxSpeedMCS = 1;
13083 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13084 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013085 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053013086 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070013087 {
13088 maxRate = myRate;
13089 if (rate_flags & eHAL_TX_RATE_LEGACY)
13090 {
13091 maxSpeedMCS = 0;
13092 }
13093 else
13094 {
13095 maxSpeedMCS = 1;
13096 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13097 }
13098 }
13099
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013100 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070013101 {
13102 sinfo->txrate.legacy = maxRate;
13103#ifdef LINKSPEED_DEBUG_ENABLED
13104 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
13105#endif //LINKSPEED_DEBUG_ENABLED
13106 }
13107 else
13108 {
13109 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070013110#ifdef WLAN_FEATURE_11AC
13111 sinfo->txrate.nss = 1;
13112 if (rate_flags & eHAL_TX_RATE_VHT80)
13113 {
13114 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013115 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070013116 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013117 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070013118 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013119 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13120 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13121 }
13122 else if (rate_flags & eHAL_TX_RATE_VHT20)
13123 {
13124 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13125 }
13126#endif /* WLAN_FEATURE_11AC */
13127 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
13128 {
13129 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13130 if (rate_flags & eHAL_TX_RATE_HT40)
13131 {
13132 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13133 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013134 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013135 if (rate_flags & eHAL_TX_RATE_SGI)
13136 {
13137 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13138 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013139
Jeff Johnson295189b2012-06-20 16:38:30 -070013140#ifdef LINKSPEED_DEBUG_ENABLED
13141 pr_info("Reporting MCS rate %d flags %x\n",
13142 sinfo->txrate.mcs,
13143 sinfo->txrate.flags );
13144#endif //LINKSPEED_DEBUG_ENABLED
13145 }
13146 }
13147 else
13148 {
13149 // report current rate instead of max rate
13150
13151 if (rate_flags & eHAL_TX_RATE_LEGACY)
13152 {
13153 //provide to the UI in units of 100kbps
13154 sinfo->txrate.legacy = myRate;
13155#ifdef LINKSPEED_DEBUG_ENABLED
13156 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
13157#endif //LINKSPEED_DEBUG_ENABLED
13158 }
13159 else
13160 {
13161 //must be MCS
13162 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013163#ifdef WLAN_FEATURE_11AC
13164 sinfo->txrate.nss = 1;
13165 if (rate_flags & eHAL_TX_RATE_VHT80)
13166 {
13167 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13168 }
13169 else
13170#endif /* WLAN_FEATURE_11AC */
13171 {
13172 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13173 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013174 if (rate_flags & eHAL_TX_RATE_SGI)
13175 {
13176 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13177 }
13178 if (rate_flags & eHAL_TX_RATE_HT40)
13179 {
13180 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13181 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013182#ifdef WLAN_FEATURE_11AC
13183 else if (rate_flags & eHAL_TX_RATE_VHT80)
13184 {
13185 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
13186 }
13187#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070013188#ifdef LINKSPEED_DEBUG_ENABLED
13189 pr_info("Reporting actual MCS rate %d flags %x\n",
13190 sinfo->txrate.mcs,
13191 sinfo->txrate.flags );
13192#endif //LINKSPEED_DEBUG_ENABLED
13193 }
13194 }
13195 sinfo->filled |= STATION_INFO_TX_BITRATE;
13196
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013197 sinfo->tx_packets =
13198 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
13199 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
13200 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
13201 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
13202
13203 sinfo->tx_retries =
13204 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
13205 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
13206 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
13207 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
13208
13209 sinfo->tx_failed =
13210 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
13211 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
13212 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
13213 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
13214
13215 sinfo->filled |=
13216 STATION_INFO_TX_PACKETS |
13217 STATION_INFO_TX_RETRIES |
13218 STATION_INFO_TX_FAILED;
13219
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013220 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13221 TRACE_CODE_HDD_CFG80211_GET_STA,
13222 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013223 EXIT();
13224 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013225}
13226
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013227static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13228 u8* mac, struct station_info *sinfo)
13229{
13230 int ret;
13231
13232 vos_ssr_protect(__func__);
13233 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
13234 vos_ssr_unprotect(__func__);
13235
13236 return ret;
13237}
13238
13239static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070013240 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070013241{
13242 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013243 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013244 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013245 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013246
Jeff Johnsone7245742012-09-05 17:12:55 -070013247 ENTER();
13248
Jeff Johnson295189b2012-06-20 16:38:30 -070013249 if (NULL == pAdapter)
13250 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013251 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013252 return -ENODEV;
13253 }
13254
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013255 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13256 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
13257 pAdapter->sessionId, timeout));
13258
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013259 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013260 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013261 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013262 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013263 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013264 }
13265
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013266 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
13267 (TRUE == pHddCtx->hdd_wlan_suspended) &&
13268 (pHddCtx->cfg_ini->fhostArpOffload) &&
13269 (eConnectionState_Associated ==
13270 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13271 {
Amar Singhald53568e2013-09-26 11:03:45 -070013272
13273 hddLog(VOS_TRACE_LEVEL_INFO,
13274 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053013275 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013276 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13277 {
13278 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013279 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013280 __func__, vos_status);
13281 }
13282 }
13283
Jeff Johnson295189b2012-06-20 16:38:30 -070013284 /**The get power cmd from the supplicant gets updated by the nl only
13285 *on successful execution of the function call
13286 *we are oppositely mapped w.r.t mode in the driver
13287 **/
13288 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
13289
13290 if (VOS_STATUS_E_FAILURE == vos_status)
13291 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13293 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013294 return -EINVAL;
13295 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013296 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013297 return 0;
13298}
13299
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013300static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
13301 struct net_device *dev, bool mode, int timeout)
13302{
13303 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013304
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013305 vos_ssr_protect(__func__);
13306 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
13307 vos_ssr_unprotect(__func__);
13308
13309 return ret;
13310}
Jeff Johnson295189b2012-06-20 16:38:30 -070013311#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013312static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
13313 struct net_device *netdev,
13314 u8 key_index)
13315{
13316 ENTER();
13317 return 0;
13318}
13319
Jeff Johnson295189b2012-06-20 16:38:30 -070013320static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013321 struct net_device *netdev,
13322 u8 key_index)
13323{
13324 int ret;
13325 vos_ssr_protect(__func__);
13326 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
13327 vos_ssr_unprotect(__func__);
13328 return ret;
13329}
13330#endif //LINUX_VERSION_CODE
13331
13332#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13333static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13334 struct net_device *dev,
13335 struct ieee80211_txq_params *params)
13336{
13337 ENTER();
13338 return 0;
13339}
13340#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13341static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13342 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013343{
Jeff Johnsone7245742012-09-05 17:12:55 -070013344 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013345 return 0;
13346}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013347#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070013348
13349#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13350static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013351 struct net_device *dev,
13352 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013353{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013354 int ret;
13355
13356 vos_ssr_protect(__func__);
13357 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
13358 vos_ssr_unprotect(__func__);
13359 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013360}
13361#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13362static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
13363 struct ieee80211_txq_params *params)
13364{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013365 int ret;
13366
13367 vos_ssr_protect(__func__);
13368 ret = __wlan_hdd_set_txq_params(wiphy, params);
13369 vos_ssr_unprotect(__func__);
13370 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013371}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013372#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013373
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013374static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013375 struct net_device *dev,
13376 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070013377{
13378 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013379 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013380 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013381 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013382 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013383 v_CONTEXT_t pVosContext = NULL;
13384 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013385
Jeff Johnsone7245742012-09-05 17:12:55 -070013386 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013387
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013388 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070013389 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013390 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013391 return -EINVAL;
13392 }
13393
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013394 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13395 TRACE_CODE_HDD_CFG80211_DEL_STA,
13396 pAdapter->sessionId, pAdapter->device_mode));
13397
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013398 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13399 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013400 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013401 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013402 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013403 }
13404
Jeff Johnson295189b2012-06-20 16:38:30 -070013405 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013406 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013407 )
13408 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013409 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13410 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13411 if(pSapCtx == NULL){
13412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13413 FL("psapCtx is NULL"));
13414 return -ENOENT;
13415 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013416 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013417 {
13418 v_U16_t i;
13419 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13420 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013421 if ((pSapCtx->aStaInfo[i].isUsed) &&
13422 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070013423 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013424 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013425 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013426 ETHER_ADDR_LEN);
13427
Jeff Johnson295189b2012-06-20 16:38:30 -070013428 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013429 "%s: Delete STA with MAC::"
13430 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013431 __func__,
13432 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
13433 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013434 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013435 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013436 }
13437 }
13438 }
13439 else
13440 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013441
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013442 vos_status = hdd_softap_GetStaId(pAdapter,
13443 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013444 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13445 {
13446 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013447 "%s: Skip this DEL STA as this is not used::"
13448 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013449 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013450 return -ENOENT;
13451 }
13452
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013453 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013454 {
13455 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013456 "%s: Skip this DEL STA as deauth is in progress::"
13457 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013458 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013459 return -ENOENT;
13460 }
13461
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013462 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013463
Jeff Johnson295189b2012-06-20 16:38:30 -070013464 hddLog(VOS_TRACE_LEVEL_INFO,
13465 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013466 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013467 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013468 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013469
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013470 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013471 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13472 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013473 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013474 hddLog(VOS_TRACE_LEVEL_INFO,
13475 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013476 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013477 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013478 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013479 return -ENOENT;
13480 }
13481
Jeff Johnson295189b2012-06-20 16:38:30 -070013482 }
13483 }
13484
13485 EXIT();
13486
13487 return 0;
13488}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013489
13490#ifdef CFG80211_DEL_STA_V2
13491static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13492 struct net_device *dev,
13493 struct station_del_parameters *param)
13494#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013495static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13496 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013497#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013498{
13499 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013500 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070013501
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013502 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013503
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013504#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013505 if (NULL == param) {
13506 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013507 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013508 return -EINVAL;
13509 }
13510
13511 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
13512 param->subtype, &delStaParams);
13513
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013514#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053013515 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013516 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013517#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013518 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
13519
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013520 vos_ssr_unprotect(__func__);
13521
13522 return ret;
13523}
13524
13525static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013526 struct net_device *dev, u8 *mac, struct station_parameters *params)
13527{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013528 hdd_adapter_t *pAdapter;
13529 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013530 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013531#ifdef FEATURE_WLAN_TDLS
13532 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013533
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013534 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013535
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013536 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13537 if (NULL == pAdapter)
13538 {
13539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13540 "%s: Adapter is NULL",__func__);
13541 return -EINVAL;
13542 }
13543 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13544 status = wlan_hdd_validate_context(pHddCtx);
13545 if (0 != status)
13546 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013547 return status;
13548 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013549
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013550 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13551 TRACE_CODE_HDD_CFG80211_ADD_STA,
13552 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013553 mask = params->sta_flags_mask;
13554
13555 set = params->sta_flags_set;
13556
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053013557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013558 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
13559 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013560
13561 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13562 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013563 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013564 }
13565 }
13566#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013567 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013568 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013569}
13570
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013571static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
13572 struct net_device *dev, u8 *mac, struct station_parameters *params)
13573{
13574 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013575
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013576 vos_ssr_protect(__func__);
13577 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
13578 vos_ssr_unprotect(__func__);
13579
13580 return ret;
13581}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013582#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070013583
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013584static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070013585 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013586{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013587 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13588 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013589 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013590 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013591 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013592 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070013593
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013594 ENTER();
13595
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013596 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013597 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013598 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013599 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013600 return -EINVAL;
13601 }
13602
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013603 if (!pmksa) {
13604 hddLog(LOGE, FL("pmksa is NULL"));
13605 return -EINVAL;
13606 }
13607
13608 if (!pmksa->bssid || !pmksa->pmkid) {
13609 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
13610 pmksa->bssid, pmksa->pmkid);
13611 return -EINVAL;
13612 }
13613
13614 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
13615 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13616
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013617 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13618 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013619 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013620 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013621 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013622 }
13623
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013624 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013625 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13626
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013627 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
13628 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013629
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013630 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013631 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013632 &pmk_id, 1, FALSE);
13633
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013634 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13635 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
13636 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013637
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013638 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013639 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013640}
13641
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013642static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
13643 struct cfg80211_pmksa *pmksa)
13644{
13645 int ret;
13646
13647 vos_ssr_protect(__func__);
13648 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
13649 vos_ssr_unprotect(__func__);
13650
13651 return ret;
13652}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013653
Wilson Yang6507c4e2013-10-01 20:11:19 -070013654
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013655static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070013656 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013657{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013658 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13659 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013660 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013661 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013662
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013663 ENTER();
13664
Wilson Yang6507c4e2013-10-01 20:11:19 -070013665 /* Validate pAdapter */
13666 if (NULL == pAdapter)
13667 {
13668 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
13669 return -EINVAL;
13670 }
13671
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013672 if (!pmksa) {
13673 hddLog(LOGE, FL("pmksa is NULL"));
13674 return -EINVAL;
13675 }
13676
13677 if (!pmksa->bssid) {
13678 hddLog(LOGE, FL("pmksa->bssid is NULL"));
13679 return -EINVAL;
13680 }
13681
Kiet Lam98c46a12014-10-31 15:34:57 -070013682 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
13683 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13684
Wilson Yang6507c4e2013-10-01 20:11:19 -070013685 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13686 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070013687 if (0 != status)
13688 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070013689 return status;
13690 }
13691
13692 /*Retrieve halHandle*/
13693 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13694
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013695 /* Delete the PMKID CSR cache */
13696 if (eHAL_STATUS_SUCCESS !=
13697 sme_RoamDelPMKIDfromCache(halHandle,
13698 pAdapter->sessionId, pmksa->bssid, FALSE)) {
13699 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
13700 MAC_ADDR_ARRAY(pmksa->bssid));
13701 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013702 }
13703
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013704 EXIT();
13705 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013706}
13707
Wilson Yang6507c4e2013-10-01 20:11:19 -070013708
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013709static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
13710 struct cfg80211_pmksa *pmksa)
13711{
13712 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013713
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013714 vos_ssr_protect(__func__);
13715 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
13716 vos_ssr_unprotect(__func__);
13717
13718 return ret;
13719
13720}
13721
13722static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013723{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013724 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13725 tHalHandle halHandle;
13726 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013727 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013728
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013729 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070013730
13731 /* Validate pAdapter */
13732 if (NULL == pAdapter)
13733 {
13734 hddLog(VOS_TRACE_LEVEL_ERROR,
13735 "%s: Invalid Adapter" ,__func__);
13736 return -EINVAL;
13737 }
13738
13739 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13740 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070013741 if (0 != status)
13742 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070013743 return status;
13744 }
13745
13746 /*Retrieve halHandle*/
13747 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13748
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013749 /* Flush the PMKID cache in CSR */
13750 if (eHAL_STATUS_SUCCESS !=
13751 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
13752 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
13753 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013754 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013755 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080013756 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013757}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013758
13759static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
13760{
13761 int ret;
13762
13763 vos_ssr_protect(__func__);
13764 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
13765 vos_ssr_unprotect(__func__);
13766
13767 return ret;
13768}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013769#endif
13770
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013771#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013772static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13773 struct net_device *dev,
13774 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013775{
13776 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13777 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013778 hdd_context_t *pHddCtx;
13779 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013780
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013781 ENTER();
13782
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013783 if (NULL == pAdapter)
13784 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013785 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013786 return -ENODEV;
13787 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013788 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13789 ret = wlan_hdd_validate_context(pHddCtx);
13790 if (0 != ret)
13791 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013792 return ret;
13793 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013794 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013795 if (NULL == pHddStaCtx)
13796 {
13797 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
13798 return -EINVAL;
13799 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013800
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013801 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13802 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
13803 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013804 // Added for debug on reception of Re-assoc Req.
13805 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
13806 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013807 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013808 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080013809 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013810 }
13811
13812#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080013813 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013814 ftie->ie_len);
13815#endif
13816
13817 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013818 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13819 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013820 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013821
13822 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013823 return 0;
13824}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013825
13826static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13827 struct net_device *dev,
13828 struct cfg80211_update_ft_ies_params *ftie)
13829{
13830 int ret;
13831
13832 vos_ssr_protect(__func__);
13833 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
13834 vos_ssr_unprotect(__func__);
13835
13836 return ret;
13837}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013838#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013839
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013840#ifdef FEATURE_WLAN_SCAN_PNO
13841
13842void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
13843 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
13844{
13845 int ret;
13846 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
13847 hdd_context_t *pHddCtx;
13848
Nirav Shah80830bf2013-12-31 16:35:12 +053013849 ENTER();
13850
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013851 if (NULL == pAdapter)
13852 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013854 "%s: HDD adapter is Null", __func__);
13855 return ;
13856 }
13857
13858 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13859 if (NULL == pHddCtx)
13860 {
13861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13862 "%s: HDD context is Null!!!", __func__);
13863 return ;
13864 }
13865
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013866 spin_lock(&pHddCtx->schedScan_lock);
13867 if (TRUE == pHddCtx->isWiphySuspended)
13868 {
13869 pHddCtx->isSchedScanUpdatePending = TRUE;
13870 spin_unlock(&pHddCtx->schedScan_lock);
13871 hddLog(VOS_TRACE_LEVEL_INFO,
13872 "%s: Update cfg80211 scan database after it resume", __func__);
13873 return ;
13874 }
13875 spin_unlock(&pHddCtx->schedScan_lock);
13876
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013877 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
13878
13879 if (0 > ret)
13880 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
13881
13882 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013883 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13884 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013885}
13886
13887/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013888 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013889 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013890 */
13891static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
13892{
13893 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13894 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013895 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013896 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13897 int status = 0;
13898 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13899
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013900 /* The current firmware design does not allow PNO during any
13901 * active sessions. Hence, determine the active sessions
13902 * and return a failure.
13903 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013904 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
13905 {
13906 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013907 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013908
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013909 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
13910 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
13911 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
13912 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
13913 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053013914 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013915 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013916 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013917 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013918 }
13919 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13920 pAdapterNode = pNext;
13921 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013922 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013923}
13924
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013925void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
13926{
13927 hdd_adapter_t *pAdapter = callbackContext;
13928 hdd_context_t *pHddCtx;
13929
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013930 ENTER();
13931
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013932 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
13933 {
13934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13935 FL("Invalid adapter or adapter has invalid magic"));
13936 return;
13937 }
13938
13939 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13940 if (0 != wlan_hdd_validate_context(pHddCtx))
13941 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013942 return;
13943 }
13944
c_hpothub53c45d2014-08-18 16:53:14 +053013945 if (VOS_STATUS_SUCCESS != status)
13946 {
13947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013948 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053013949 pHddCtx->isPnoEnable = FALSE;
13950 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013951
13952 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
13953 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013954 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013955}
13956
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013957/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013958 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
13959 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013960 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013961static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013962 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13963{
13964 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053013965 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013966 hdd_context_t *pHddCtx;
13967 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013968 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053013969 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
13970 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013971 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13972 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013973 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013974 hdd_config_t *pConfig = NULL;
13975 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013976
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013977 ENTER();
13978
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013979 if (NULL == pAdapter)
13980 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013982 "%s: HDD adapter is Null", __func__);
13983 return -ENODEV;
13984 }
13985
13986 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013987 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013988
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013989 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013990 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013991 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013992 }
13993
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013994 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013995 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13996 if (NULL == hHal)
13997 {
13998 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13999 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014000 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014001 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053014002 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014003 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053014004 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014005 {
14006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14007 "%s: aborting the existing scan is unsuccessfull", __func__);
14008 return -EBUSY;
14009 }
14010
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014011 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014012 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014014 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014015 return -EBUSY;
14016 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014017
c_hpothu37f21312014-04-09 21:49:54 +053014018 if (TRUE == pHddCtx->isPnoEnable)
14019 {
14020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14021 FL("already PNO is enabled"));
14022 return -EBUSY;
14023 }
c_hpothu225aa7c2014-10-22 17:45:13 +053014024
14025 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
14026 {
14027 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14028 "%s: abort ROC failed ", __func__);
14029 return -EBUSY;
14030 }
14031
c_hpothu37f21312014-04-09 21:49:54 +053014032 pHddCtx->isPnoEnable = TRUE;
14033
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014034 pnoRequest.enable = 1; /*Enable PNO */
14035 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014036
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014037 if (( !pnoRequest.ucNetworksCount ) ||
14038 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014039 {
14040 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014041 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014042 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014043 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014044 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014045 goto error;
14046 }
14047
14048 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
14049 {
14050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014051 "%s: Incorrect number of channels %d",
14052 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014053 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014054 goto error;
14055 }
14056
14057 /* Framework provides one set of channels(all)
14058 * common for all saved profile */
14059 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14060 channels_allowed, &num_channels_allowed))
14061 {
14062 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14063 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014064 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014065 goto error;
14066 }
14067 /* Checking each channel against allowed channel list */
14068 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053014069 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014070 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014071 char chList [(request->n_channels*5)+1];
14072 int len;
14073 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014074 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014075 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014076 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014077 if (request->channels[i]->hw_value == channels_allowed[indx])
14078 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014079 if ((!pConfig->enableDFSPnoChnlScan) &&
14080 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
14081 {
14082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14083 "%s : Dropping DFS channel : %d",
14084 __func__,channels_allowed[indx]);
14085 num_ignore_dfs_ch++;
14086 break;
14087 }
14088
Nirav Shah80830bf2013-12-31 16:35:12 +053014089 valid_ch[num_ch++] = request->channels[i]->hw_value;
14090 len += snprintf(chList+len, 5, "%d ",
14091 request->channels[i]->hw_value);
14092 break ;
14093 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014094 }
14095 }
Nirav Shah80830bf2013-12-31 16:35:12 +053014096 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014097
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014098 /*If all channels are DFS and dropped, then ignore the PNO request*/
14099 if (num_ignore_dfs_ch == request->n_channels)
14100 {
14101 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14102 "%s : All requested channels are DFS channels", __func__);
14103 ret = -EINVAL;
14104 goto error;
14105 }
14106 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014107
14108 pnoRequest.aNetworks =
14109 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14110 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014111 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014112 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14113 FL("failed to allocate memory aNetworks %u"),
14114 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14115 goto error;
14116 }
14117 vos_mem_zero(pnoRequest.aNetworks,
14118 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14119
14120 /* Filling per profile params */
14121 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
14122 {
14123 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014124 request->match_sets[i].ssid.ssid_len;
14125
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014126 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
14127 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014128 {
14129 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014130 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014131 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014132 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014133 goto error;
14134 }
14135
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014136 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014137 request->match_sets[i].ssid.ssid,
14138 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14140 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014141 i, pnoRequest.aNetworks[i].ssId.ssId);
14142 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
14143 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
14144 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014145
14146 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014147 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
14148 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014149
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014150 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014151 }
14152
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014153 for (i = 0; i < request->n_ssids; i++)
14154 {
14155 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014156 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014157 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014158 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014159 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014160 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014161 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014162 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014163 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014164 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014165 break;
14166 }
14167 j++;
14168 }
14169 }
14170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14171 "Number of hidden networks being Configured = %d",
14172 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080014174 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014175
14176 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14177 if (pnoRequest.p24GProbeTemplate == NULL)
14178 {
14179 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14180 FL("failed to allocate memory p24GProbeTemplate %u"),
14181 SIR_PNO_MAX_PB_REQ_SIZE);
14182 goto error;
14183 }
14184
14185 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14186 if (pnoRequest.p5GProbeTemplate == NULL)
14187 {
14188 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14189 FL("failed to allocate memory p5GProbeTemplate %u"),
14190 SIR_PNO_MAX_PB_REQ_SIZE);
14191 goto error;
14192 }
14193
14194 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14195 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14196
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053014197 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
14198 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014199 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014200 pnoRequest.us24GProbeTemplateLen = request->ie_len;
14201 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
14202 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014203
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014204 pnoRequest.us5GProbeTemplateLen = request->ie_len;
14205 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
14206 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014207 }
14208
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014209 /* Driver gets only one time interval which is hardcoded in
14210 * supplicant for 10000ms. Taking power consumption into account 6 timers
14211 * will be used, Timervalue is increased exponentially i.e 10,20,40,
14212 * 80,160,320 secs. And number of scan cycle for each timer
14213 * is configurable through INI param gPNOScanTimerRepeatValue.
14214 * If it is set to 0 only one timer will be used and PNO scan cycle
14215 * will be repeated after each interval specified by supplicant
14216 * till PNO is disabled.
14217 */
14218 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014219 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014220 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014221 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014222 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
14223
14224 tempInterval = (request->interval)/1000;
14225 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14226 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
14227 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014228 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014229 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014230 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014231 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014232 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014233 tempInterval *= 2;
14234 }
14235 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014236 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014237
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014238 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014239
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014240 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014241 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
14242 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014243 pAdapter->pno_req_status = 0;
14244
Nirav Shah80830bf2013-12-31 16:35:12 +053014245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14246 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014247 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
14248 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053014249
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014250 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014251 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014252 hdd_cfg80211_sched_scan_done_callback, pAdapter);
14253 if (eHAL_STATUS_SUCCESS != status)
14254 {
14255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014256 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014257 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014258 goto error;
14259 }
14260
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014261 ret = wait_for_completion_timeout(
14262 &pAdapter->pno_comp_var,
14263 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
14264 if (0 >= ret)
14265 {
14266 // Did not receive the response for PNO enable in time.
14267 // Assuming the PNO enable was success.
14268 // Returning error from here, because we timeout, results
14269 // in side effect of Wifi (Wifi Setting) not to work.
14270 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14271 FL("Timed out waiting for PNO to be Enabled"));
14272 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014273 }
14274
14275 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053014276 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014277
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014278error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014279 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14280 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053014281 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014282 if (pnoRequest.aNetworks)
14283 vos_mem_free(pnoRequest.aNetworks);
14284 if (pnoRequest.p24GProbeTemplate)
14285 vos_mem_free(pnoRequest.p24GProbeTemplate);
14286 if (pnoRequest.p5GProbeTemplate)
14287 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014288
14289 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014290 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014291}
14292
14293/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014294 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
14295 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014296 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014297static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
14298 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14299{
14300 int ret;
14301
14302 vos_ssr_protect(__func__);
14303 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
14304 vos_ssr_unprotect(__func__);
14305
14306 return ret;
14307}
14308
14309/*
14310 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
14311 * Function to disable PNO
14312 */
14313static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014314 struct net_device *dev)
14315{
14316 eHalStatus status = eHAL_STATUS_FAILURE;
14317 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14318 hdd_context_t *pHddCtx;
14319 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014320 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014321 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014322
14323 ENTER();
14324
14325 if (NULL == pAdapter)
14326 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014328 "%s: HDD adapter is Null", __func__);
14329 return -ENODEV;
14330 }
14331
14332 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014333
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014334 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014335 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014337 "%s: HDD context is Null", __func__);
14338 return -ENODEV;
14339 }
14340
14341 /* The return 0 is intentional when isLogpInProgress and
14342 * isLoadUnloadInProgress. We did observe a crash due to a return of
14343 * failure in sched_scan_stop , especially for a case where the unload
14344 * of the happens at the same time. The function __cfg80211_stop_sched_scan
14345 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
14346 * success. If it returns a failure , then its next invocation due to the
14347 * clean up of the second interface will have the dev pointer corresponding
14348 * to the first one leading to a crash.
14349 */
14350 if (pHddCtx->isLogpInProgress)
14351 {
14352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14353 "%s: LOGP in Progress. Ignore!!!", __func__);
14354 return ret;
14355 }
14356
Mihir Shete18156292014-03-11 15:38:30 +053014357 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014358 {
14359 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14360 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14361 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014362 }
14363
14364 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14365 if (NULL == hHal)
14366 {
14367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14368 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014369 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014370 }
14371
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014372 pnoRequest.enable = 0; /* Disable PNO */
14373 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014374
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014375 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014376 pAdapter->sessionId,
14377 NULL, pAdapter);
14378 if (eHAL_STATUS_SUCCESS != status)
14379 {
14380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14381 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014382 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014383 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014384 }
c_hpothu37f21312014-04-09 21:49:54 +053014385 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014386
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014387error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014389 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014390
14391 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014392 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014393}
14394
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014395/*
14396 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
14397 * NL interface to disable PNO
14398 */
14399static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
14400 struct net_device *dev)
14401{
14402 int ret;
14403
14404 vos_ssr_protect(__func__);
14405 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
14406 vos_ssr_unprotect(__func__);
14407
14408 return ret;
14409}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014410#endif /*FEATURE_WLAN_SCAN_PNO*/
14411
14412
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014413#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014414#if TDLS_MGMT_VERSION2
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014415static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014416 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014417 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
14418#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014419static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014420 u8 *peer, u8 action_code, u8 dialog_token,
14421 u16 status_code, const u8 *buf, size_t len)
14422#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014423{
14424
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014425 hdd_adapter_t *pAdapter;
14426 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014427 u8 peerMac[6];
14428 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070014429 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080014430 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070014431 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014432 int ret;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014433#if !(TDLS_MGMT_VERSION2)
14434 u32 peer_capability = 0;
14435#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014436 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014437
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014438 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14439 if (NULL == pAdapter)
14440 {
14441 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14442 "%s: Adapter is NULL",__func__);
14443 return -EINVAL;
14444 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014445 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14446 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
14447 pAdapter->sessionId, action_code));
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014448 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014449 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014450 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014452 "Invalid arguments");
14453 return -EINVAL;
14454 }
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014455 if (pHddCtx->isLogpInProgress)
14456 {
14457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14458 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053014459 wlan_hdd_tdls_set_link_status(pAdapter,
14460 peer,
14461 eTDLS_LINK_IDLE,
14462 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014463 return -EBUSY;
14464 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014465 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
14466 {
14467 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14468 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14469 return -EAGAIN;
14470 }
Hoonki Lee27511902013-03-14 18:19:06 -070014471 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014472 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070014474 "%s: TDLS mode is disabled OR not enabled in FW."
14475 MAC_ADDRESS_STR " action %d declined.",
14476 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014477 return -ENOTSUPP;
14478 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014479
Hoonki Lee27511902013-03-14 18:19:06 -070014480 /* other than teardown frame, other mgmt frames are not sent if disabled */
14481 if (SIR_MAC_TDLS_TEARDOWN != action_code)
14482 {
14483 /* if tdls_mode is disabled to respond to peer's request */
14484 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
14485 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014486 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070014487 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014488 " TDLS mode is disabled. action %d declined.",
14489 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070014490
14491 return -ENOTSUPP;
14492 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014493
14494 if (vos_max_concurrent_connections_reached())
14495 {
14496 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14497 return -EINVAL;
14498 }
Hoonki Lee27511902013-03-14 18:19:06 -070014499 }
14500
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014501 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
14502 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014503 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014504 {
14505 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014506 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014507 " TDLS setup is ongoing. action %d declined.",
14508 __func__, MAC_ADDR_ARRAY(peer), action_code);
14509 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014510 }
14511 }
14512
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014513 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
14514 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080014515 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014516 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14517 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014518 {
14519 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
14520 we return error code at 'add_station()'. Hence we have this
14521 check again in addtion to add_station().
14522 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014523 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014524 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14526 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014527 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
14528 __func__, MAC_ADDR_ARRAY(peer), action_code,
14529 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053014530 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080014531 }
14532 else
14533 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014534 /* maximum reached. tweak to send error code to peer and return
14535 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014536 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14538 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014539 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
14540 __func__, MAC_ADDR_ARRAY(peer), status_code,
14541 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070014542 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014543 /* fall through to send setup resp with failure status
14544 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014545 }
14546 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014547 else
14548 {
14549 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014550 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014551 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014552 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014554 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
14555 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014556 return -EPERM;
14557 }
14558 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014559 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014560 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014561
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014563 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014564 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
14565 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014566
Hoonki Leea34dd892013-02-05 22:56:02 -080014567 /*Except teardown responder will not be used so just make 0*/
14568 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014569 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080014570 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014571
14572 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014573 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014574
14575 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
14576 responder = pTdlsPeer->is_responder;
14577 else
Hoonki Leea34dd892013-02-05 22:56:02 -080014578 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014580 "%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 -070014581 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
14582 dialog_token, status_code, len);
14583 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080014584 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014585 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014586
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014587 /* For explicit trigger of DIS_REQ come out of BMPS for
14588 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070014589 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014590 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
14591 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070014592 {
14593 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
14594 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014596 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070014597 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
14598 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014599 if (SIR_MAC_TDLS_DIS_REQ != action_code)
14600 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070014601 }
14602
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014603 /* make sure doesn't call send_mgmt() while it is pending */
14604 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
14605 {
14606 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014607 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014608 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014609 ret = -EBUSY;
14610 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014611 }
14612
14613 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014614 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
14615
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014616 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053014617 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014618
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014619 if (VOS_STATUS_SUCCESS != status)
14620 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14622 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014623 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014624 ret = -EINVAL;
14625 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014626 }
14627
Hoonki Leed37cbb32013-04-20 00:31:14 -070014628 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
14629 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
14630
14631 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014632 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070014633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014634 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070014635 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014636 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080014637
14638 if (pHddCtx->isLogpInProgress)
14639 {
14640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14641 "%s: LOGP in Progress. Ignore!!!", __func__);
14642 return -EAGAIN;
14643 }
14644
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014645 ret = -EINVAL;
14646 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014647 }
14648
Gopichand Nakkala05922802013-03-14 12:23:19 -070014649 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070014650 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014651 ret = max_sta_failed;
14652 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070014653 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014654
Hoonki Leea34dd892013-02-05 22:56:02 -080014655 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
14656 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014657 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014658 }
14659 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
14660 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014661 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014662 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014663
14664 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014665
14666tx_failed:
14667 /* add_station will be called before sending TDLS_SETUP_REQ and
14668 * TDLS_SETUP_RSP and as part of add_station driver will enable
14669 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
14670 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
14671 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
14672 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
14673 */
14674
14675 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
14676 (SIR_MAC_TDLS_SETUP_RSP == action_code))
14677 wlan_hdd_tdls_check_bmps(pAdapter);
14678 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014679}
14680
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014681#if TDLS_MGMT_VERSION2
14682static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14683 u8 *peer, u8 action_code, u8 dialog_token,
14684 u16 status_code, u32 peer_capability,
14685 const u8 *buf, size_t len)
14686#else
14687static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14688 u8 *peer, u8 action_code, u8 dialog_token,
14689 u16 status_code, const u8 *buf, size_t len)
14690#endif
14691{
14692 int ret;
14693
14694 vos_ssr_protect(__func__);
14695#if TDLS_MGMT_VERSION2
14696 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14697 status_code, peer_capability, buf, len);
14698#else
14699 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14700 status_code, buf, len);
14701#endif
14702 vos_ssr_unprotect(__func__);
14703
14704 return ret;
14705}
Atul Mittal115287b2014-07-08 13:26:33 +053014706
14707int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
14708 u8 *peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014709 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053014710 cfg80211_exttdls_callback callback)
14711{
14712
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014713 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053014714 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014715 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053014716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14717 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
14718 __func__, MAC_ADDR_ARRAY(peer));
14719
14720 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14721 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14722
14723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14724 " %s TDLS External control and Implicit Trigger not enabled ",
14725 __func__);
14726 return -ENOTSUPP;
14727 }
14728
14729 /* To cater the requirement of establishing the TDLS link
14730 * irrespective of the data traffic , get an entry of TDLS peer.
14731 */
14732 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
14733 if (pTdlsPeer == NULL) {
14734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14735 "%s: peer " MAC_ADDRESS_STR " not existing",
14736 __func__, MAC_ADDR_ARRAY(peer));
14737 return -EINVAL;
14738 }
14739
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053014740 /* check FW TDLS Off Channel capability */
14741 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
14742 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014743 {
14744 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
14745 pTdlsPeer->peerParams.global_operating_class =
14746 tdls_peer_params->global_operating_class;
14747 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
14748 pTdlsPeer->peerParams.min_bandwidth_kbps =
14749 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014750 /* check configured channel is valid, non dfs and
14751 * not current operating channel */
14752 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
14753 tdls_peer_params->channel)) &&
14754 (pHddStaCtx) &&
14755 (tdls_peer_params->channel !=
14756 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014757 {
14758 pTdlsPeer->isOffChannelConfigured = TRUE;
14759 }
14760 else
14761 {
14762 pTdlsPeer->isOffChannelConfigured = FALSE;
14763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14764 "%s: Configured Tdls Off Channel is not valid", __func__);
14765
14766 }
14767 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014768 "%s: tdls_off_channel %d isOffChannelConfigured %d "
14769 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014770 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014771 pTdlsPeer->isOffChannelConfigured,
14772 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014773 }
14774 else
14775 {
14776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053014777 "%s: TDLS off channel FW capability %d or "
14778 "Invalid TDLS Peer Params", __func__,
14779 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014780 }
14781
Atul Mittal115287b2014-07-08 13:26:33 +053014782 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
14783
14784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14785 " %s TDLS Add Force Peer Failed",
14786 __func__);
14787 return -EINVAL;
14788 }
14789 /*EXT TDLS*/
14790
14791 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
14792 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14793 " %s TDLS set callback Failed",
14794 __func__);
14795 return -EINVAL;
14796 }
14797
14798 return(0);
14799
14800}
14801
14802int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
14803{
14804
14805 hddTdlsPeer_t *pTdlsPeer;
14806 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14808 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
14809 __func__, MAC_ADDR_ARRAY(peer));
14810
14811 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14812 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14813
14814 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14815 " %s TDLS External control and Implicit Trigger not enabled ",
14816 __func__);
14817 return -ENOTSUPP;
14818 }
14819
14820
14821 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14822
14823 if ( NULL == pTdlsPeer ) {
14824 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
14825 " peer not exsting",
14826 __func__, MAC_ADDR_ARRAY(peer));
14827 return -EINVAL;
14828 }
14829 else {
14830 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
14831 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014832 /* if channel switch is configured, reset
14833 the channel for this peer */
14834 if (TRUE == pTdlsPeer->isOffChannelConfigured)
14835 {
14836 pTdlsPeer->peerParams.channel = 0;
14837 pTdlsPeer->isOffChannelConfigured = FALSE;
14838 }
Atul Mittal115287b2014-07-08 13:26:33 +053014839 }
14840
14841 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
14842 return -EINVAL;
14843
14844 /*EXT TDLS*/
14845
14846 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
14847
14848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14849 " %s TDLS set callback Failed",
14850 __func__);
14851 return -EINVAL;
14852 }
14853 return(0);
14854
14855}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014856static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014857 u8 *peer, enum nl80211_tdls_operation oper)
14858{
14859 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14860 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014861 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014862 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014863
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014864 ENTER();
14865
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014866 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14867 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
14868 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014869 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014870 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014871 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014872 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014873 return -EINVAL;
14874 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014875
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014876 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014877 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014878 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014879 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014880 }
14881
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014882
14883 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014884 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014885 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014887 "TDLS Disabled in INI OR not enabled in FW. "
14888 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014889 return -ENOTSUPP;
14890 }
14891
14892 switch (oper) {
14893 case NL80211_TDLS_ENABLE_LINK:
14894 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014895 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014896 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014897 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053014898 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014899 tANI_U16 numCurrTdlsPeers = 0;
14900 hddTdlsPeer_t *connPeer = NULL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014901
Sunil Dutt41de4e22013-11-14 18:09:02 +053014902 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053014903 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053014904 if ( NULL == pTdlsPeer ) {
14905 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
14906 " (oper %d) not exsting. ignored",
14907 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
14908 return -EINVAL;
14909 }
14910
14911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14912 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
14913 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
14914 "NL80211_TDLS_ENABLE_LINK");
14915
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070014916 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
14917 {
14918 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
14919 MAC_ADDRESS_STR " failed",
14920 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
14921 return -EINVAL;
14922 }
14923
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014924 /* TDLS Off Channel, Disable tdls channel switch,
14925 when there are more than one tdls link */
14926 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14927 if (numCurrTdlsPeers == 1)
14928 {
14929 /* get connected peer and send disable tdls off chan */
14930 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
14931 if (connPeer && (connPeer->isOffChannelConfigured == TRUE))
14932 {
14933 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14934 "%s: More then one peer connected, Disable "
14935 "TDLS channel switch", __func__);
14936
14937 sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
14938 pAdapter->sessionId,
14939 connPeer->peerMac,
14940 connPeer->peerParams.channel,
14941 TDLS_OFF_CHANNEL_BW_OFFSET,
14942 TDLS_CHANNEL_SWITCH_DISABLE);
14943 }
14944 else
14945 {
14946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14947 "%s: No TDLS Connected Peer or "
14948 "isOffChannelConfigured %d",
14949 __func__,
14950 (connPeer ? connPeer->isOffChannelConfigured : -1));
14951 }
14952 }
14953
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014954 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014955 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014956 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053014957
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014958 if (0 != wlan_hdd_tdls_get_link_establish_params(
14959 pAdapter, peer,&tdlsLinkEstablishParams)) {
14960 return -EINVAL;
14961 }
14962 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014963
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014964 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
14965 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
14966 /* Send TDLS peer UAPSD capabilities to the firmware and
14967 * register with the TL on after the response for this operation
14968 * is received .
14969 */
14970 ret = wait_for_completion_interruptible_timeout(
14971 &pAdapter->tdls_link_establish_req_comp,
14972 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
14973 if (ret <= 0)
14974 {
14975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14976 "%s: Link Establish Request Faled Status %ld",
14977 __func__, ret);
14978 return -EINVAL;
14979 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014980 }
Atul Mittal115287b2014-07-08 13:26:33 +053014981 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14982 eTDLS_LINK_CONNECTED,
14983 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053014984 staDesc.ucSTAId = pTdlsPeer->staId;
14985 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
14986 WLANTL_UpdateTdlsSTAClient(pHddCtx->pvosContext,
14987 &staDesc);
14988
14989
Gopichand Nakkala471708b2013-06-04 20:03:01 +053014990 /* Mark TDLS client Authenticated .*/
14991 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
14992 pTdlsPeer->staId,
14993 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014994 if (VOS_STATUS_SUCCESS == status)
14995 {
Hoonki Lee14621352013-04-16 17:51:19 -070014996 if (pTdlsPeer->is_responder == 0)
14997 {
14998 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
14999
15000 wlan_hdd_tdls_timer_restart(pAdapter,
15001 &pTdlsPeer->initiatorWaitTimeoutTimer,
15002 WAIT_TIME_TDLS_INITIATOR);
15003 /* suspend initiator TX until it receives direct packet from the
15004 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
15005 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15006 &staId, NULL);
15007 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015008 wlan_hdd_tdls_increment_peer_count(pAdapter);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015009
15010 /* TDLS Off Channel, Enable tdls channel switch,
15011 when their is only one tdls link and it supports */
15012 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15013 if ((numCurrTdlsPeers == 1) &&
15014 (TRUE == pTdlsPeer->isOffChannelSupported) &&
15015 (TRUE == pTdlsPeer->isOffChannelConfigured))
15016 {
15017 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15018 "%s: Send TDLS channel switch request for channel %d",
15019 __func__, pTdlsPeer->peerParams.channel);
15020 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
15021 pAdapter->sessionId,
15022 pTdlsPeer->peerMac,
15023 pTdlsPeer->peerParams.channel,
15024 TDLS_OFF_CHANNEL_BW_OFFSET,
15025 TDLS_CHANNEL_SWITCH_ENABLE);
15026 }
15027 else
15028 {
15029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15030 "%s: TDLS channel switch request not sent"
15031 " numCurrTdlsPeers %d "
15032 "isOffChannelSupported %d "
15033 "isOffChannelConfigured %d",
15034 __func__, numCurrTdlsPeers,
15035 pTdlsPeer->isOffChannelSupported,
15036 pTdlsPeer->isOffChannelConfigured);
15037 }
15038
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015039 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015040 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015041
15042 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015043 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
15044 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015045 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015046 int ac;
15047 uint8 ucAc[4] = { WLANTL_AC_VO,
15048 WLANTL_AC_VI,
15049 WLANTL_AC_BK,
15050 WLANTL_AC_BE };
15051 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
15052 for(ac=0; ac < 4; ac++)
15053 {
15054 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15055 pTdlsPeer->staId, ucAc[ac],
15056 tlTid[ac], tlTid[ac], 0, 0,
15057 WLANTL_BI_DIR );
15058 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015059 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015060 }
15061
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015062 }
15063 break;
15064 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080015065 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015066 tANI_U16 numCurrTdlsPeers = 0;
15067 hddTdlsPeer_t *connPeer = NULL;
15068
Sunil Dutt41de4e22013-11-14 18:09:02 +053015069 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15070
15071 if ( NULL == pTdlsPeer ) {
15072 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15073 " (oper %d) not exsting. ignored",
15074 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15075 return -EINVAL;
15076 }
15077
15078 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15079 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15080 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15081 "NL80211_TDLS_DISABLE_LINK");
15082
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015083 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080015084 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015085 long status;
15086
Atul Mittal271a7652014-09-12 13:18:22 +053015087
15088 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15089 eTDLS_LINK_TEARING,
15090 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
15091 eTDLS_LINK_UNSPECIFIED:
15092 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015093 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
15094
Lee Hoonkic1262f22013-01-24 21:59:00 -080015095 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
15096 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015097
15098 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
15099 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053015100 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053015101 eTDLS_LINK_IDLE,
15102 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015103 if (status <= 0)
15104 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15106 "%s: Del station failed status %ld",
15107 __func__, status);
15108 return -EPERM;
15109 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015110
15111 /* TDLS Off Channel, Enable tdls channel switch,
15112 when their is only one tdls link and it supports */
15113 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15114 if (numCurrTdlsPeers == 1)
15115 {
15116 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
15117 if ((connPeer) &&
15118 (connPeer->isOffChannelSupported == TRUE) &&
15119 (connPeer->isOffChannelConfigured == TRUE))
15120 {
15121 sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
15122 pAdapter->sessionId,
15123 connPeer->peerMac,
15124 connPeer->peerParams.channel,
15125 TDLS_OFF_CHANNEL_BW_OFFSET,
15126 TDLS_CHANNEL_SWITCH_ENABLE);
15127 }
15128 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15129 "%s: TDLS channel switch "
15130 "isOffChannelSupported %d "
15131 "isOffChannelConfigured %d",
15132 __func__,
15133 (connPeer ? connPeer->isOffChannelSupported : -1),
15134 (connPeer ? connPeer->isOffChannelConfigured : -1));
15135 }
15136 else
15137 {
15138 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15139 "%s: TDLS channel switch request not sent "
15140 "numCurrTdlsPeers %d ",
15141 __func__, numCurrTdlsPeers);
15142 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015143 }
15144 else
15145 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15147 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080015148 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015149 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015150 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015151 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015152 {
Atul Mittal115287b2014-07-08 13:26:33 +053015153 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015154
Atul Mittal115287b2014-07-08 13:26:33 +053015155 if (0 != status)
15156 {
15157 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15158 "%s: Error in TDLS Teardown", __func__);
15159 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015160 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053015161 break;
15162 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015163 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015164 {
Atul Mittal115287b2014-07-08 13:26:33 +053015165 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
15166 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015167 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053015168 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015169
Atul Mittal115287b2014-07-08 13:26:33 +053015170 if (0 != status)
15171 {
15172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15173 "%s: Error in TDLS Setup", __func__);
15174 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053015175 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053015176 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015177 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015178 case NL80211_TDLS_DISCOVERY_REQ:
15179 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15181 "%s: We don't support in-driver setup/teardown/discovery "
15182 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015183 return -ENOTSUPP;
15184 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15186 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015187 return -ENOTSUPP;
15188 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015189
15190 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015191 return 0;
15192}
Chilam NG571c65a2013-01-19 12:27:36 +053015193
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015194static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
15195 u8 *peer, enum nl80211_tdls_operation oper)
15196{
15197 int ret;
15198
15199 vos_ssr_protect(__func__);
15200 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
15201 vos_ssr_unprotect(__func__);
15202
15203 return ret;
15204}
15205
Chilam NG571c65a2013-01-19 12:27:36 +053015206int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
15207 struct net_device *dev, u8 *peer)
15208{
Arif Hussaina7c8e412013-11-20 11:06:42 -080015209 hddLog(VOS_TRACE_LEVEL_INFO,
15210 "tdls send discover req: "MAC_ADDRESS_STR,
15211 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053015212
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015213#if TDLS_MGMT_VERSION2
15214 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15215 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15216#else
Chilam NG571c65a2013-01-19 12:27:36 +053015217 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15218 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015219#endif
Chilam NG571c65a2013-01-19 12:27:36 +053015220}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015221#endif
15222
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015223#ifdef WLAN_FEATURE_GTK_OFFLOAD
15224/*
15225 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
15226 * Callback rountine called upon receiving response for
15227 * get offload info
15228 */
15229void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
15230 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
15231{
15232
15233 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015234 tANI_U8 tempReplayCounter[8];
15235 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015236
15237 ENTER();
15238
15239 if (NULL == pAdapter)
15240 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053015241 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015242 "%s: HDD adapter is Null", __func__);
15243 return ;
15244 }
15245
15246 if (NULL == pGtkOffloadGetInfoRsp)
15247 {
15248 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15249 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
15250 return ;
15251 }
15252
15253 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
15254 {
15255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15256 "%s: wlan Failed to get replay counter value",
15257 __func__);
15258 return ;
15259 }
15260
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015261 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15262 /* Update replay counter */
15263 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
15264 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15265
15266 {
15267 /* changing from little to big endian since supplicant
15268 * works on big endian format
15269 */
15270 int i;
15271 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15272
15273 for (i = 0; i < 8; i++)
15274 {
15275 tempReplayCounter[7-i] = (tANI_U8)p[i];
15276 }
15277 }
15278
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015279 /* Update replay counter to NL */
15280 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015281 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015282}
15283
15284/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015285 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015286 * This function is used to offload GTK rekeying job to the firmware.
15287 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015288int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015289 struct cfg80211_gtk_rekey_data *data)
15290{
15291 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15292 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15293 hdd_station_ctx_t *pHddStaCtx;
15294 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015295 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015296 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015297 eHalStatus status = eHAL_STATUS_FAILURE;
15298
15299 ENTER();
15300
15301 if (NULL == pAdapter)
15302 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015304 "%s: HDD adapter is Null", __func__);
15305 return -ENODEV;
15306 }
15307
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015308 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15309 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
15310 pAdapter->sessionId, pAdapter->device_mode));
15311
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015312 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015313 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015314 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015315 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015316 }
15317
15318 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15319 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15320 if (NULL == hHal)
15321 {
15322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15323 "%s: HAL context is Null!!!", __func__);
15324 return -EAGAIN;
15325 }
15326
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015327 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
15328 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
15329 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
15330 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015331 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015332 {
15333 /* changing from big to little endian since driver
15334 * works on little endian format
15335 */
15336 tANI_U8 *p =
15337 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
15338 int i;
15339
15340 for (i = 0; i < 8; i++)
15341 {
15342 p[7-i] = data->replay_ctr[i];
15343 }
15344 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015345
15346 if (TRUE == pHddCtx->hdd_wlan_suspended)
15347 {
15348 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015349 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
15350 sizeof (tSirGtkOffloadParams));
15351 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015352 pAdapter->sessionId);
15353
15354 if (eHAL_STATUS_SUCCESS != status)
15355 {
15356 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15357 "%s: sme_SetGTKOffload failed, returned %d",
15358 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053015359
15360 /* Need to clear any trace of key value in the memory.
15361 * Thus zero out the memory even though it is local
15362 * variable.
15363 */
15364 vos_mem_zero(&hddGtkOffloadReqParams,
15365 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015366 return status;
15367 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015368 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15369 "%s: sme_SetGTKOffload successfull", __func__);
15370 }
15371 else
15372 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15374 "%s: wlan not suspended GTKOffload request is stored",
15375 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015376 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015377
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053015378 /* Need to clear any trace of key value in the memory.
15379 * Thus zero out the memory even though it is local
15380 * variable.
15381 */
15382 vos_mem_zero(&hddGtkOffloadReqParams,
15383 sizeof(hddGtkOffloadReqParams));
15384
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015385 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015386 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015387}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015388
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015389int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
15390 struct cfg80211_gtk_rekey_data *data)
15391{
15392 int ret;
15393
15394 vos_ssr_protect(__func__);
15395 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
15396 vos_ssr_unprotect(__func__);
15397
15398 return ret;
15399}
15400#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015401/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015402 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015403 * This function is used to set access control policy
15404 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015405static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15406 struct net_device *dev,
15407 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015408{
15409 int i;
15410 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15411 hdd_hostapd_state_t *pHostapdState;
15412 tsap_Config_t *pConfig;
15413 v_CONTEXT_t pVosContext = NULL;
15414 hdd_context_t *pHddCtx;
15415 int status;
15416
15417 ENTER();
15418
15419 if (NULL == pAdapter)
15420 {
15421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15422 "%s: HDD adapter is Null", __func__);
15423 return -ENODEV;
15424 }
15425
15426 if (NULL == params)
15427 {
15428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15429 "%s: params is Null", __func__);
15430 return -EINVAL;
15431 }
15432
15433 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15434 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015435 if (0 != status)
15436 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015437 return status;
15438 }
15439
15440 pVosContext = pHddCtx->pvosContext;
15441 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
15442
15443 if (NULL == pHostapdState)
15444 {
15445 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15446 "%s: pHostapdState is Null", __func__);
15447 return -EINVAL;
15448 }
15449
15450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
15451 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
15452
15453 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
15454 {
15455 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
15456
15457 /* default value */
15458 pConfig->num_accept_mac = 0;
15459 pConfig->num_deny_mac = 0;
15460
15461 /**
15462 * access control policy
15463 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
15464 * listed in hostapd.deny file.
15465 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
15466 * listed in hostapd.accept file.
15467 */
15468 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
15469 {
15470 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
15471 }
15472 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
15473 {
15474 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
15475 }
15476 else
15477 {
15478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15479 "%s:Acl Policy : %d is not supported",
15480 __func__, params->acl_policy);
15481 return -ENOTSUPP;
15482 }
15483
15484 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
15485 {
15486 pConfig->num_accept_mac = params->n_acl_entries;
15487 for (i = 0; i < params->n_acl_entries; i++)
15488 {
15489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15490 "** Add ACL MAC entry %i in WhiletList :"
15491 MAC_ADDRESS_STR, i,
15492 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
15493
15494 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
15495 sizeof(qcmacaddr));
15496 }
15497 }
15498 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
15499 {
15500 pConfig->num_deny_mac = params->n_acl_entries;
15501 for (i = 0; i < params->n_acl_entries; i++)
15502 {
15503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15504 "** Add ACL MAC entry %i in BlackList :"
15505 MAC_ADDRESS_STR, i,
15506 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
15507
15508 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
15509 sizeof(qcmacaddr));
15510 }
15511 }
15512
15513 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
15514 {
15515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15516 "%s: SAP Set Mac Acl fail", __func__);
15517 return -EINVAL;
15518 }
15519 }
15520 else
15521 {
15522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015523 "%s: Invalid device_mode = %s (%d)",
15524 __func__, hdd_device_modetoString(pAdapter->device_mode),
15525 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015526 return -EINVAL;
15527 }
15528
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015529 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015530 return 0;
15531}
15532
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015533static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15534 struct net_device *dev,
15535 const struct cfg80211_acl_data *params)
15536{
15537 int ret;
15538 vos_ssr_protect(__func__);
15539 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
15540 vos_ssr_unprotect(__func__);
15541
15542 return ret;
15543}
15544
Leo Chang9056f462013-08-01 19:21:11 -070015545#ifdef WLAN_NL80211_TESTMODE
15546#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070015547void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070015548(
15549 void *pAdapter,
15550 void *indCont
15551)
15552{
Leo Changd9df8aa2013-09-26 13:32:26 -070015553 tSirLPHBInd *lphbInd;
15554 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053015555 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070015556
15557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070015558 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070015559
c_hpothu73f35e62014-04-18 13:40:08 +053015560 if (pAdapter == NULL)
15561 {
15562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15563 "%s: pAdapter is NULL\n",__func__);
15564 return;
15565 }
15566
Leo Chang9056f462013-08-01 19:21:11 -070015567 if (NULL == indCont)
15568 {
15569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070015570 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070015571 return;
15572 }
15573
c_hpothu73f35e62014-04-18 13:40:08 +053015574 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070015575 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070015576 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053015577 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070015578 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070015579 GFP_ATOMIC);
15580 if (!skb)
15581 {
15582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15583 "LPHB timeout, NL buffer alloc fail");
15584 return;
15585 }
15586
Leo Changac3ba772013-10-07 09:47:04 -070015587 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070015588 {
15589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15590 "WLAN_HDD_TM_ATTR_CMD put fail");
15591 goto nla_put_failure;
15592 }
Leo Changac3ba772013-10-07 09:47:04 -070015593 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070015594 {
15595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15596 "WLAN_HDD_TM_ATTR_TYPE put fail");
15597 goto nla_put_failure;
15598 }
Leo Changac3ba772013-10-07 09:47:04 -070015599 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070015600 sizeof(tSirLPHBInd), lphbInd))
15601 {
15602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15603 "WLAN_HDD_TM_ATTR_DATA put fail");
15604 goto nla_put_failure;
15605 }
Leo Chang9056f462013-08-01 19:21:11 -070015606 cfg80211_testmode_event(skb, GFP_ATOMIC);
15607 return;
15608
15609nla_put_failure:
15610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15611 "NLA Put fail");
15612 kfree_skb(skb);
15613
15614 return;
15615}
15616#endif /* FEATURE_WLAN_LPHB */
15617
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015618static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070015619{
15620 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
15621 int err = 0;
15622#ifdef FEATURE_WLAN_LPHB
15623 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070015624 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015625
15626 ENTER();
15627
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015628 err = wlan_hdd_validate_context(pHddCtx);
15629 if (0 != err)
15630 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015631 return err;
15632 }
Leo Chang9056f462013-08-01 19:21:11 -070015633#endif /* FEATURE_WLAN_LPHB */
15634
15635 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
15636 if (err)
15637 {
15638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15639 "%s Testmode INV ATTR", __func__);
15640 return err;
15641 }
15642
15643 if (!tb[WLAN_HDD_TM_ATTR_CMD])
15644 {
15645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15646 "%s Testmode INV CMD", __func__);
15647 return -EINVAL;
15648 }
15649
15650 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
15651 {
15652#ifdef FEATURE_WLAN_LPHB
15653 /* Low Power Heartbeat configuration request */
15654 case WLAN_HDD_TM_CMD_WLAN_HB:
15655 {
15656 int buf_len;
15657 void *buf;
15658 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080015659 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070015660
15661 if (!tb[WLAN_HDD_TM_ATTR_DATA])
15662 {
15663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15664 "%s Testmode INV DATA", __func__);
15665 return -EINVAL;
15666 }
15667
15668 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
15669 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080015670
15671 hb_params_temp =(tSirLPHBReq *)buf;
15672 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
15673 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
15674 return -EINVAL;
15675
Leo Chang9056f462013-08-01 19:21:11 -070015676 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
15677 if (NULL == hb_params)
15678 {
15679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15680 "%s Request Buffer Alloc Fail", __func__);
15681 return -EINVAL;
15682 }
15683
15684 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070015685 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
15686 hb_params,
15687 wlan_hdd_cfg80211_lphb_ind_handler);
15688 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070015689 {
Leo Changd9df8aa2013-09-26 13:32:26 -070015690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15691 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070015692 vos_mem_free(hb_params);
15693 }
Leo Chang9056f462013-08-01 19:21:11 -070015694 return 0;
15695 }
15696#endif /* FEATURE_WLAN_LPHB */
15697 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15699 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070015700 return -EOPNOTSUPP;
15701 }
15702
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015703 EXIT();
15704 return err;
Leo Chang9056f462013-08-01 19:21:11 -070015705}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015706
15707static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
15708{
15709 int ret;
15710
15711 vos_ssr_protect(__func__);
15712 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
15713 vos_ssr_unprotect(__func__);
15714
15715 return ret;
15716}
Leo Chang9056f462013-08-01 19:21:11 -070015717#endif /* CONFIG_NL80211_TESTMODE */
15718
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015719static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015720 struct net_device *dev,
15721 int idx, struct survey_info *survey)
15722{
15723 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15724 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053015725 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015726 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053015727 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015728 v_S7_t snr,rssi;
15729 int status, i, j, filled = 0;
15730
15731 ENTER();
15732
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015733 if (NULL == pAdapter)
15734 {
15735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15736 "%s: HDD adapter is Null", __func__);
15737 return -ENODEV;
15738 }
15739
15740 if (NULL == wiphy)
15741 {
15742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15743 "%s: wiphy is Null", __func__);
15744 return -ENODEV;
15745 }
15746
15747 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15748 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015749 if (0 != status)
15750 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015751 return status;
15752 }
15753
Mihir Sheted9072e02013-08-21 17:02:29 +053015754 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15755
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015756 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053015757 0 != pAdapter->survey_idx ||
15758 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015759 {
15760 /* The survey dump ops when implemented completely is expected to
15761 * return a survey of all channels and the ops is called by the
15762 * kernel with incremental values of the argument 'idx' till it
15763 * returns -ENONET. But we can only support the survey for the
15764 * operating channel for now. survey_idx is used to track
15765 * that the ops is called only once and then return -ENONET for
15766 * the next iteration
15767 */
15768 pAdapter->survey_idx = 0;
15769 return -ENONET;
15770 }
15771
15772 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15773
15774 wlan_hdd_get_snr(pAdapter, &snr);
15775 wlan_hdd_get_rssi(pAdapter, &rssi);
15776
15777 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
15778 hdd_wlan_get_freq(channel, &freq);
15779
15780
15781 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
15782 {
15783 if (NULL == wiphy->bands[i])
15784 {
15785 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
15786 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
15787 continue;
15788 }
15789
15790 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
15791 {
15792 struct ieee80211_supported_band *band = wiphy->bands[i];
15793
15794 if (band->channels[j].center_freq == (v_U16_t)freq)
15795 {
15796 survey->channel = &band->channels[j];
15797 /* The Rx BDs contain SNR values in dB for the received frames
15798 * while the supplicant expects noise. So we calculate and
15799 * return the value of noise (dBm)
15800 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
15801 */
15802 survey->noise = rssi - snr;
15803 survey->filled = SURVEY_INFO_NOISE_DBM;
15804 filled = 1;
15805 }
15806 }
15807 }
15808
15809 if (filled)
15810 pAdapter->survey_idx = 1;
15811 else
15812 {
15813 pAdapter->survey_idx = 0;
15814 return -ENONET;
15815 }
15816
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015817 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015818 return 0;
15819}
15820
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015821static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
15822 struct net_device *dev,
15823 int idx, struct survey_info *survey)
15824{
15825 int ret;
15826
15827 vos_ssr_protect(__func__);
15828 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
15829 vos_ssr_unprotect(__func__);
15830
15831 return ret;
15832}
15833
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015834/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015835 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015836 * this is called when cfg80211 driver resume
15837 * driver updates latest sched_scan scan result(if any) to cfg80211 database
15838 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015839int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015840{
15841 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15842 hdd_adapter_t *pAdapter;
15843 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15844 VOS_STATUS status = VOS_STATUS_SUCCESS;
15845
15846 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015847
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015848 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015849 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015850 return 0;
15851 }
15852
15853 spin_lock(&pHddCtx->schedScan_lock);
15854 pHddCtx->isWiphySuspended = FALSE;
15855 if (TRUE != pHddCtx->isSchedScanUpdatePending)
15856 {
15857 spin_unlock(&pHddCtx->schedScan_lock);
15858 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15859 "%s: Return resume is not due to PNO indication", __func__);
15860 return 0;
15861 }
15862 // Reset flag to avoid updatating cfg80211 data old results again
15863 pHddCtx->isSchedScanUpdatePending = FALSE;
15864 spin_unlock(&pHddCtx->schedScan_lock);
15865
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015866
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015867 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15868
15869 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15870 {
15871 pAdapter = pAdapterNode->pAdapter;
15872 if ( (NULL != pAdapter) &&
15873 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
15874 {
15875 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015876 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015877 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15878 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015879 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015880 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015881 {
15882 /* Acquire wakelock to handle the case where APP's tries to
15883 * suspend immediately after updating the scan results. Whis
15884 * results in app's is in suspended state and not able to
15885 * process the connect request to AP
15886 */
15887 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015888 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015889 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015890
15891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15892 "%s : cfg80211 scan result database updated", __func__);
15893
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015894 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015895 return 0;
15896
15897 }
15898 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15899 pAdapterNode = pNext;
15900 }
15901
15902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15903 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015904 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015905 return 0;
15906}
15907
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015908int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
15909{
15910 int ret;
15911
15912 vos_ssr_protect(__func__);
15913 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
15914 vos_ssr_unprotect(__func__);
15915
15916 return ret;
15917}
15918
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015919/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015920 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015921 * this is called when cfg80211 driver suspends
15922 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015923int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015924 struct cfg80211_wowlan *wow)
15925{
15926 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015927 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015928
15929 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015930
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015931 ret = wlan_hdd_validate_context(pHddCtx);
15932 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015933 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015934 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015935 }
15936
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015937
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015938 pHddCtx->isWiphySuspended = TRUE;
15939
15940 EXIT();
15941
15942 return 0;
15943}
15944
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015945int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
15946 struct cfg80211_wowlan *wow)
15947{
15948 int ret;
15949
15950 vos_ssr_protect(__func__);
15951 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
15952 vos_ssr_unprotect(__func__);
15953
15954 return ret;
15955}
Jeff Johnson295189b2012-06-20 16:38:30 -070015956/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015957static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070015958{
15959 .add_virtual_intf = wlan_hdd_add_virtual_intf,
15960 .del_virtual_intf = wlan_hdd_del_virtual_intf,
15961 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
15962 .change_station = wlan_hdd_change_station,
15963#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
15964 .add_beacon = wlan_hdd_cfg80211_add_beacon,
15965 .del_beacon = wlan_hdd_cfg80211_del_beacon,
15966 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015967#else
15968 .start_ap = wlan_hdd_cfg80211_start_ap,
15969 .change_beacon = wlan_hdd_cfg80211_change_beacon,
15970 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070015971#endif
15972 .change_bss = wlan_hdd_cfg80211_change_bss,
15973 .add_key = wlan_hdd_cfg80211_add_key,
15974 .get_key = wlan_hdd_cfg80211_get_key,
15975 .del_key = wlan_hdd_cfg80211_del_key,
15976 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015977#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070015978 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015979#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015980 .scan = wlan_hdd_cfg80211_scan,
15981 .connect = wlan_hdd_cfg80211_connect,
15982 .disconnect = wlan_hdd_cfg80211_disconnect,
15983 .join_ibss = wlan_hdd_cfg80211_join_ibss,
15984 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
15985 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
15986 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
15987 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070015988 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
15989 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053015990 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070015991#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15992 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
15993 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
15994 .set_txq_params = wlan_hdd_set_txq_params,
15995#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015996 .get_station = wlan_hdd_cfg80211_get_station,
15997 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
15998 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015999 .add_station = wlan_hdd_cfg80211_add_station,
16000#ifdef FEATURE_WLAN_LFR
16001 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
16002 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
16003 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
16004#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016005#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
16006 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
16007#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016008#ifdef FEATURE_WLAN_TDLS
16009 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
16010 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
16011#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016012#ifdef WLAN_FEATURE_GTK_OFFLOAD
16013 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
16014#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016015#ifdef FEATURE_WLAN_SCAN_PNO
16016 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
16017 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
16018#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016019 .resume = wlan_hdd_cfg80211_resume_wlan,
16020 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016021 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070016022#ifdef WLAN_NL80211_TESTMODE
16023 .testmode_cmd = wlan_hdd_cfg80211_testmode,
16024#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016025 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070016026};
16027