blob: fab6be00dc0b6482802a9173b550b7e7c84dc0c5 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
99
Jeff Johnson295189b2012-06-20 16:38:30 -0700100
101#define g_mode_rates_size (12)
102#define a_mode_rates_size (8)
103#define FREQ_BASE_80211G (2407)
104#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700105#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530106#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700107#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800108 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700109
110#define HDD2GHZCHAN(freq, chan, flag) { \
111 .band = IEEE80211_BAND_2GHZ, \
112 .center_freq = (freq), \
113 .hw_value = (chan),\
114 .flags = (flag), \
115 .max_antenna_gain = 0 ,\
116 .max_power = 30, \
117}
118
119#define HDD5GHZCHAN(freq, chan, flag) { \
120 .band = IEEE80211_BAND_5GHZ, \
121 .center_freq = (freq), \
122 .hw_value = (chan),\
123 .flags = (flag), \
124 .max_antenna_gain = 0 ,\
125 .max_power = 30, \
126}
127
128#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
129{\
130 .bitrate = rate, \
131 .hw_value = rate_id, \
132 .flags = flag, \
133}
134
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530135#ifdef WLAN_FEATURE_VOWIFI_11R
136#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
137#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
138#endif
139
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530140#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530141#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530142
Sunil Duttc69bccb2014-05-26 21:30:20 +0530143#ifdef WLAN_FEATURE_LINK_LAYER_STATS
144/*
145 * Used to allocate the size of 4096 for the link layer stats.
146 * The size of 4096 is considered assuming that all data per
147 * respective event fit with in the limit.Please take a call
148 * on the limit based on the data requirements on link layer
149 * statistics.
150 */
151#define LL_STATS_EVENT_BUF_SIZE 4096
152#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530153#ifdef WLAN_FEATURE_EXTSCAN
154/*
155 * Used to allocate the size of 4096 for the EXTScan NL data.
156 * The size of 4096 is considered assuming that all data per
157 * respective event fit with in the limit.Please take a call
158 * on the limit based on the data requirements.
159 */
160
161#define EXTSCAN_EVENT_BUF_SIZE 4096
162#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
163#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530164
Atul Mittal115287b2014-07-08 13:26:33 +0530165/*EXT TDLS*/
166/*
167 * Used to allocate the size of 4096 for the TDLS.
168 * The size of 4096 is considered assuming that all data per
169 * respective event fit with in the limit.Please take a call
170 * on the limit based on the data requirements on link layer
171 * statistics.
172 */
173#define EXTTDLS_EVENT_BUF_SIZE 4096
174
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530175static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700176{
177 WLAN_CIPHER_SUITE_WEP40,
178 WLAN_CIPHER_SUITE_WEP104,
179 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800180#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700181#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
182 WLAN_CIPHER_SUITE_KRK,
183 WLAN_CIPHER_SUITE_CCMP,
184#else
185 WLAN_CIPHER_SUITE_CCMP,
186#endif
187#ifdef FEATURE_WLAN_WAPI
188 WLAN_CIPHER_SUITE_SMS4,
189#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700190#ifdef WLAN_FEATURE_11W
191 WLAN_CIPHER_SUITE_AES_CMAC,
192#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700193};
194
195static inline int is_broadcast_ether_addr(const u8 *addr)
196{
197 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
198 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
199}
200
201static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530202{
Jeff Johnson295189b2012-06-20 16:38:30 -0700203 HDD2GHZCHAN(2412, 1, 0) ,
204 HDD2GHZCHAN(2417, 2, 0) ,
205 HDD2GHZCHAN(2422, 3, 0) ,
206 HDD2GHZCHAN(2427, 4, 0) ,
207 HDD2GHZCHAN(2432, 5, 0) ,
208 HDD2GHZCHAN(2437, 6, 0) ,
209 HDD2GHZCHAN(2442, 7, 0) ,
210 HDD2GHZCHAN(2447, 8, 0) ,
211 HDD2GHZCHAN(2452, 9, 0) ,
212 HDD2GHZCHAN(2457, 10, 0) ,
213 HDD2GHZCHAN(2462, 11, 0) ,
214 HDD2GHZCHAN(2467, 12, 0) ,
215 HDD2GHZCHAN(2472, 13, 0) ,
216 HDD2GHZCHAN(2484, 14, 0) ,
217};
218
Jeff Johnson295189b2012-06-20 16:38:30 -0700219static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
220{
221 HDD2GHZCHAN(2412, 1, 0) ,
222 HDD2GHZCHAN(2437, 6, 0) ,
223 HDD2GHZCHAN(2462, 11, 0) ,
224};
Jeff Johnson295189b2012-06-20 16:38:30 -0700225
226static struct ieee80211_channel hdd_channels_5_GHZ[] =
227{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700228 HDD5GHZCHAN(4920, 240, 0) ,
229 HDD5GHZCHAN(4940, 244, 0) ,
230 HDD5GHZCHAN(4960, 248, 0) ,
231 HDD5GHZCHAN(4980, 252, 0) ,
232 HDD5GHZCHAN(5040, 208, 0) ,
233 HDD5GHZCHAN(5060, 212, 0) ,
234 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700235 HDD5GHZCHAN(5180, 36, 0) ,
236 HDD5GHZCHAN(5200, 40, 0) ,
237 HDD5GHZCHAN(5220, 44, 0) ,
238 HDD5GHZCHAN(5240, 48, 0) ,
239 HDD5GHZCHAN(5260, 52, 0) ,
240 HDD5GHZCHAN(5280, 56, 0) ,
241 HDD5GHZCHAN(5300, 60, 0) ,
242 HDD5GHZCHAN(5320, 64, 0) ,
243 HDD5GHZCHAN(5500,100, 0) ,
244 HDD5GHZCHAN(5520,104, 0) ,
245 HDD5GHZCHAN(5540,108, 0) ,
246 HDD5GHZCHAN(5560,112, 0) ,
247 HDD5GHZCHAN(5580,116, 0) ,
248 HDD5GHZCHAN(5600,120, 0) ,
249 HDD5GHZCHAN(5620,124, 0) ,
250 HDD5GHZCHAN(5640,128, 0) ,
251 HDD5GHZCHAN(5660,132, 0) ,
252 HDD5GHZCHAN(5680,136, 0) ,
253 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800254#ifdef FEATURE_WLAN_CH144
255 HDD5GHZCHAN(5720,144, 0) ,
256#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700257 HDD5GHZCHAN(5745,149, 0) ,
258 HDD5GHZCHAN(5765,153, 0) ,
259 HDD5GHZCHAN(5785,157, 0) ,
260 HDD5GHZCHAN(5805,161, 0) ,
261 HDD5GHZCHAN(5825,165, 0) ,
262};
263
264static struct ieee80211_rate g_mode_rates[] =
265{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530266 HDD_G_MODE_RATETAB(10, 0x1, 0),
267 HDD_G_MODE_RATETAB(20, 0x2, 0),
268 HDD_G_MODE_RATETAB(55, 0x4, 0),
269 HDD_G_MODE_RATETAB(110, 0x8, 0),
270 HDD_G_MODE_RATETAB(60, 0x10, 0),
271 HDD_G_MODE_RATETAB(90, 0x20, 0),
272 HDD_G_MODE_RATETAB(120, 0x40, 0),
273 HDD_G_MODE_RATETAB(180, 0x80, 0),
274 HDD_G_MODE_RATETAB(240, 0x100, 0),
275 HDD_G_MODE_RATETAB(360, 0x200, 0),
276 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700277 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530278};
Jeff Johnson295189b2012-06-20 16:38:30 -0700279
280static struct ieee80211_rate a_mode_rates[] =
281{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282 HDD_G_MODE_RATETAB(60, 0x10, 0),
283 HDD_G_MODE_RATETAB(90, 0x20, 0),
284 HDD_G_MODE_RATETAB(120, 0x40, 0),
285 HDD_G_MODE_RATETAB(180, 0x80, 0),
286 HDD_G_MODE_RATETAB(240, 0x100, 0),
287 HDD_G_MODE_RATETAB(360, 0x200, 0),
288 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700289 HDD_G_MODE_RATETAB(540, 0x800, 0),
290};
291
292static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
293{
294 .channels = hdd_channels_2_4_GHZ,
295 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
296 .band = IEEE80211_BAND_2GHZ,
297 .bitrates = g_mode_rates,
298 .n_bitrates = g_mode_rates_size,
299 .ht_cap.ht_supported = 1,
300 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
301 | IEEE80211_HT_CAP_GRN_FLD
302 | IEEE80211_HT_CAP_DSSSCCK40
303 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
304 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
305 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
306 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
307 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
308 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
309};
310
Jeff Johnson295189b2012-06-20 16:38:30 -0700311static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
312{
313 .channels = hdd_social_channels_2_4_GHZ,
314 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
315 .band = IEEE80211_BAND_2GHZ,
316 .bitrates = g_mode_rates,
317 .n_bitrates = g_mode_rates_size,
318 .ht_cap.ht_supported = 1,
319 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
320 | IEEE80211_HT_CAP_GRN_FLD
321 | IEEE80211_HT_CAP_DSSSCCK40
322 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
323 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
324 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
325 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
326 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
327 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
328};
Jeff Johnson295189b2012-06-20 16:38:30 -0700329
330static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
331{
332 .channels = hdd_channels_5_GHZ,
333 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
334 .band = IEEE80211_BAND_5GHZ,
335 .bitrates = a_mode_rates,
336 .n_bitrates = a_mode_rates_size,
337 .ht_cap.ht_supported = 1,
338 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
339 | IEEE80211_HT_CAP_GRN_FLD
340 | IEEE80211_HT_CAP_DSSSCCK40
341 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
342 | IEEE80211_HT_CAP_SGI_40
343 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
344 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
345 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
346 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
347 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
348 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
349};
350
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530351/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700352 TX/RX direction for each kind of interface */
353static const struct ieee80211_txrx_stypes
354wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
355 [NL80211_IFTYPE_STATION] = {
356 .tx = 0xffff,
357 .rx = BIT(SIR_MAC_MGMT_ACTION) |
358 BIT(SIR_MAC_MGMT_PROBE_REQ),
359 },
360 [NL80211_IFTYPE_AP] = {
361 .tx = 0xffff,
362 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
363 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
364 BIT(SIR_MAC_MGMT_PROBE_REQ) |
365 BIT(SIR_MAC_MGMT_DISASSOC) |
366 BIT(SIR_MAC_MGMT_AUTH) |
367 BIT(SIR_MAC_MGMT_DEAUTH) |
368 BIT(SIR_MAC_MGMT_ACTION),
369 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700370 [NL80211_IFTYPE_ADHOC] = {
371 .tx = 0xffff,
372 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
373 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_PROBE_REQ) |
375 BIT(SIR_MAC_MGMT_DISASSOC) |
376 BIT(SIR_MAC_MGMT_AUTH) |
377 BIT(SIR_MAC_MGMT_DEAUTH) |
378 BIT(SIR_MAC_MGMT_ACTION),
379 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700380 [NL80211_IFTYPE_P2P_CLIENT] = {
381 .tx = 0xffff,
382 .rx = BIT(SIR_MAC_MGMT_ACTION) |
383 BIT(SIR_MAC_MGMT_PROBE_REQ),
384 },
385 [NL80211_IFTYPE_P2P_GO] = {
386 /* This is also same as for SoftAP */
387 .tx = 0xffff,
388 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
389 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
390 BIT(SIR_MAC_MGMT_PROBE_REQ) |
391 BIT(SIR_MAC_MGMT_DISASSOC) |
392 BIT(SIR_MAC_MGMT_AUTH) |
393 BIT(SIR_MAC_MGMT_DEAUTH) |
394 BIT(SIR_MAC_MGMT_ACTION),
395 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700396};
397
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800398#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800399static const struct ieee80211_iface_limit
400wlan_hdd_iface_limit[] = {
401 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800402 /* max = 3 ; Our driver create two interfaces during driver init
403 * wlan0 and p2p0 interfaces. p2p0 is considered as station
404 * interface until a group is formed. In JB architecture, once the
405 * group is formed, interface type of p2p0 is changed to P2P GO or
406 * Client.
407 * When supplicant remove the group, it first issue a set interface
408 * cmd to change the mode back to Station. In JB this works fine as
409 * we advertize two station type interface during driver init.
410 * Some vendors create separate interface for P2P GO/Client,
411 * after group formation(Third one). But while group remove
412 * supplicant first tries to change the mode(3rd interface) to STATION
413 * But as we advertized only two sta type interfaces nl80211 was
414 * returning error for the third one which was leading to failure in
415 * delete interface. Ideally while removing the group, supplicant
416 * should not try to change the 3rd interface mode to Station type.
417 * Till we get a fix in wpa_supplicant, we advertize max STA
418 * interface type to 3
419 */
420 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800421 .types = BIT(NL80211_IFTYPE_STATION),
422 },
423 {
424 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700425 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800426 },
427 {
428 .max = 1,
429 .types = BIT(NL80211_IFTYPE_P2P_GO) |
430 BIT(NL80211_IFTYPE_P2P_CLIENT),
431 },
432};
433
434/* By default, only single channel concurrency is allowed */
435static struct ieee80211_iface_combination
436wlan_hdd_iface_combination = {
437 .limits = wlan_hdd_iface_limit,
438 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800439 /*
440 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
441 * and p2p0 interfaces during driver init
442 * Some vendors create separate interface for P2P operations.
443 * wlan0: STA interface
444 * p2p0: P2P Device interface, action frames goes
445 * through this interface.
446 * p2p-xx: P2P interface, After GO negotiation this interface is
447 * created for p2p operations(GO/CLIENT interface).
448 */
449 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800450 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
451 .beacon_int_infra_match = false,
452};
453#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800454
Jeff Johnson295189b2012-06-20 16:38:30 -0700455static struct cfg80211_ops wlan_hdd_cfg80211_ops;
456
457/* Data rate 100KBPS based on IE Index */
458struct index_data_rate_type
459{
460 v_U8_t beacon_rate_index;
461 v_U16_t supported_rate[4];
462};
463
464/* 11B, 11G Rate table include Basic rate and Extended rate
465 The IDX field is the rate index
466 The HI field is the rate when RSSI is strong or being ignored
467 (in this case we report actual rate)
468 The MID field is the rate when RSSI is moderate
469 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
470 The LO field is the rate when RSSI is low
471 (in this case we don't report rates, actual current rate used)
472 */
473static const struct
474{
475 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700476 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700477} supported_data_rate[] =
478{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700479/* IDX HI HM LM LO (RSSI-based index */
480 {2, { 10, 10, 10, 0}},
481 {4, { 20, 20, 10, 0}},
482 {11, { 55, 20, 10, 0}},
483 {12, { 60, 55, 20, 0}},
484 {18, { 90, 55, 20, 0}},
485 {22, {110, 55, 20, 0}},
486 {24, {120, 90, 60, 0}},
487 {36, {180, 120, 60, 0}},
488 {44, {220, 180, 60, 0}},
489 {48, {240, 180, 90, 0}},
490 {66, {330, 180, 90, 0}},
491 {72, {360, 240, 90, 0}},
492 {96, {480, 240, 120, 0}},
493 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700494};
495
496/* MCS Based rate table */
497static struct index_data_rate_type supported_mcs_rate[] =
498{
499/* MCS L20 L40 S20 S40 */
500 {0, {65, 135, 72, 150}},
501 {1, {130, 270, 144, 300}},
502 {2, {195, 405, 217, 450}},
503 {3, {260, 540, 289, 600}},
504 {4, {390, 810, 433, 900}},
505 {5, {520, 1080, 578, 1200}},
506 {6, {585, 1215, 650, 1350}},
507 {7, {650, 1350, 722, 1500}}
508};
509
Leo Chang6f8870f2013-03-26 18:11:36 -0700510#ifdef WLAN_FEATURE_11AC
511
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530512#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700513
514struct index_vht_data_rate_type
515{
516 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530517 v_U16_t supported_VHT80_rate[2];
518 v_U16_t supported_VHT40_rate[2];
519 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700520};
521
522typedef enum
523{
524 DATA_RATE_11AC_MAX_MCS_7,
525 DATA_RATE_11AC_MAX_MCS_8,
526 DATA_RATE_11AC_MAX_MCS_9,
527 DATA_RATE_11AC_MAX_MCS_NA
528} eDataRate11ACMaxMcs;
529
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530530/* SSID broadcast type */
531typedef enum eSSIDBcastType
532{
533 eBCAST_UNKNOWN = 0,
534 eBCAST_NORMAL = 1,
535 eBCAST_HIDDEN = 2,
536} tSSIDBcastType;
537
Leo Chang6f8870f2013-03-26 18:11:36 -0700538/* MCS Based VHT rate table */
539static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
540{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530541/* MCS L80 S80 L40 S40 L20 S40*/
542 {0, {293, 325}, {135, 150}, {65, 72}},
543 {1, {585, 650}, {270, 300}, {130, 144}},
544 {2, {878, 975}, {405, 450}, {195, 217}},
545 {3, {1170, 1300}, {540, 600}, {260, 289}},
546 {4, {1755, 1950}, {810, 900}, {390, 433}},
547 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
548 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
549 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
550 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
551 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700552};
553#endif /* WLAN_FEATURE_11AC */
554
c_hpothu79aab322014-07-14 21:11:01 +0530555/*array index points to MCS and array value points respective rssi*/
556static int rssiMcsTbl[][10] =
557{
558/*MCS 0 1 2 3 4 5 6 7 8 9*/
559 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
560 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
561 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
562};
563
Jeff Johnson295189b2012-06-20 16:38:30 -0700564extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530565#ifdef FEATURE_WLAN_SCAN_PNO
566static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
567#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700568
Leo Chang9056f462013-08-01 19:21:11 -0700569#ifdef WLAN_NL80211_TESTMODE
570enum wlan_hdd_tm_attr
571{
572 WLAN_HDD_TM_ATTR_INVALID = 0,
573 WLAN_HDD_TM_ATTR_CMD = 1,
574 WLAN_HDD_TM_ATTR_DATA = 2,
575 WLAN_HDD_TM_ATTR_TYPE = 3,
576 /* keep last */
577 WLAN_HDD_TM_ATTR_AFTER_LAST,
578 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
579};
580
581enum wlan_hdd_tm_cmd
582{
583 WLAN_HDD_TM_CMD_WLAN_HB = 1,
584};
585
586#define WLAN_HDD_TM_DATA_MAX_LEN 5000
587
588static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
589{
590 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
591 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
592 .len = WLAN_HDD_TM_DATA_MAX_LEN },
593};
594#endif /* WLAN_NL80211_TESTMODE */
595
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800596#ifdef FEATURE_WLAN_CH_AVOID
597/*
598 * FUNCTION: wlan_hdd_send_avoid_freq_event
599 * This is called when wlan driver needs to send vendor specific
600 * avoid frequency range event to userspace
601 */
602int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
603 tHddAvoidFreqList *pAvoidFreqList)
604{
605 struct sk_buff *vendor_event;
606
607 ENTER();
608
609 if (!pHddCtx)
610 {
611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
612 "%s: HDD context is null", __func__);
613 return -1;
614 }
615
616 if (!pAvoidFreqList)
617 {
618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
619 "%s: pAvoidFreqList is null", __func__);
620 return -1;
621 }
622
623 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530624#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
625 NULL,
626#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800627 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530628 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800629 GFP_KERNEL);
630 if (!vendor_event)
631 {
632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
633 "%s: cfg80211_vendor_event_alloc failed", __func__);
634 return -1;
635 }
636
637 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
638 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
639
640 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
641
642 EXIT();
643 return 0;
644}
645#endif /* FEATURE_WLAN_CH_AVOID */
646
Srinivas Dasari030bad32015-02-18 23:23:54 +0530647/*
648 * FUNCTION: __wlan_hdd_cfg80211_nan_request
649 * This is called when wlan driver needs to send vendor specific
650 * nan request event.
651 */
652static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
653 struct wireless_dev *wdev,
654 const void *data, int data_len)
655{
656 tNanRequestReq nan_req;
657 VOS_STATUS status;
658 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530659 struct net_device *dev = wdev->netdev;
660 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
661 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530662 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
663
664 if (0 == data_len)
665 {
666 hddLog(VOS_TRACE_LEVEL_ERROR,
667 FL("NAN - Invalid Request, length = 0"));
668 return ret_val;
669 }
670
671 if (NULL == data)
672 {
673 hddLog(VOS_TRACE_LEVEL_ERROR,
674 FL("NAN - Invalid Request, data is NULL"));
675 return ret_val;
676 }
677
678 status = wlan_hdd_validate_context(pHddCtx);
679 if (0 != status)
680 {
681 hddLog(VOS_TRACE_LEVEL_ERROR,
682 FL("HDD context is not valid"));
683 return -EINVAL;
684 }
685
686 hddLog(LOG1, FL("Received NAN command"));
687 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
688 (tANI_U8 *)data, data_len);
689
690 /* check the NAN Capability */
691 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
692 {
693 hddLog(VOS_TRACE_LEVEL_ERROR,
694 FL("NAN is not supported by Firmware"));
695 return -EINVAL;
696 }
697
698 nan_req.request_data_len = data_len;
699 nan_req.request_data = data;
700
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530701 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530702 if (VOS_STATUS_SUCCESS == status)
703 {
704 ret_val = 0;
705 }
706 return ret_val;
707}
708
709/*
710 * FUNCTION: wlan_hdd_cfg80211_nan_request
711 * Wrapper to protect the nan vendor command from ssr
712 */
713static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
714 struct wireless_dev *wdev,
715 const void *data, int data_len)
716{
717 int ret;
718
719 vos_ssr_protect(__func__);
720 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
721 vos_ssr_unprotect(__func__);
722
723 return ret;
724}
725
726/*
727 * FUNCTION: wlan_hdd_cfg80211_nan_callback
728 * This is a callback function and it gets called
729 * when we need to report nan response event to
730 * upper layers.
731 */
732static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
733{
734 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
735 struct sk_buff *vendor_event;
736 int status;
737 tSirNanEvent *data;
738
739 ENTER();
740 if (NULL == msg)
741 {
742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
743 FL(" msg received here is null"));
744 return;
745 }
746 data = msg;
747
748 status = wlan_hdd_validate_context(pHddCtx);
749
750 if (0 != status)
751 {
752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
753 FL("HDD context is not valid"));
754 return;
755 }
756
757 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530758#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
759 NULL,
760#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530761 data->event_data_len +
762 NLMSG_HDRLEN,
763 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
764 GFP_KERNEL);
765
766 if (!vendor_event)
767 {
768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
769 FL("cfg80211_vendor_event_alloc failed"));
770 return;
771 }
772 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
773 data->event_data_len, data->event_data))
774 {
775 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
776 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
777 kfree_skb(vendor_event);
778 return;
779 }
780 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
781 EXIT();
782}
783
784/*
785 * FUNCTION: wlan_hdd_cfg80211_nan_init
786 * This function is called to register the callback to sme layer
787 */
788inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
789{
790 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
791}
792
793
Sunil Duttc69bccb2014-05-26 21:30:20 +0530794#ifdef WLAN_FEATURE_LINK_LAYER_STATS
795
796static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
797 struct sk_buff *vendor_event)
798{
799 if (nla_put_u8(vendor_event,
800 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
801 stats->rate.preamble) ||
802 nla_put_u8(vendor_event,
803 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
804 stats->rate.nss) ||
805 nla_put_u8(vendor_event,
806 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
807 stats->rate.bw) ||
808 nla_put_u8(vendor_event,
809 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
810 stats->rate.rateMcsIdx) ||
811 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
812 stats->rate.bitrate ) ||
813 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
814 stats->txMpdu ) ||
815 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
816 stats->rxMpdu ) ||
817 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
818 stats->mpduLost ) ||
819 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
820 stats->retries) ||
821 nla_put_u32(vendor_event,
822 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
823 stats->retriesShort ) ||
824 nla_put_u32(vendor_event,
825 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
826 stats->retriesLong))
827 {
828 hddLog(VOS_TRACE_LEVEL_ERROR,
829 FL("QCA_WLAN_VENDOR_ATTR put fail"));
830 return FALSE;
831 }
832 return TRUE;
833}
834
835static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
836 struct sk_buff *vendor_event)
837{
838 u32 i = 0;
839 struct nlattr *rateInfo;
840 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
841 stats->type) ||
842 nla_put(vendor_event,
843 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
844 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
845 nla_put_u32(vendor_event,
846 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
847 stats->capabilities) ||
848 nla_put_u32(vendor_event,
849 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
850 stats->numRate))
851 {
852 hddLog(VOS_TRACE_LEVEL_ERROR,
853 FL("QCA_WLAN_VENDOR_ATTR put fail"));
854 goto error;
855 }
856
857 rateInfo = nla_nest_start(vendor_event,
858 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530859 if(!rateInfo)
860 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530861 for (i = 0; i < stats->numRate; i++)
862 {
863 struct nlattr *rates;
864 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
865 stats->rateStats +
866 (i * sizeof(tSirWifiRateStat)));
867 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530868 if(!rates)
869 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530870
871 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
872 {
873 hddLog(VOS_TRACE_LEVEL_ERROR,
874 FL("QCA_WLAN_VENDOR_ATTR put fail"));
875 return FALSE;
876 }
877 nla_nest_end(vendor_event, rates);
878 }
879 nla_nest_end(vendor_event, rateInfo);
880
881 return TRUE;
882error:
883 return FALSE;
884}
885
886static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
887 struct sk_buff *vendor_event)
888{
889 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
890 stats->ac ) ||
891 nla_put_u32(vendor_event,
892 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
893 stats->txMpdu ) ||
894 nla_put_u32(vendor_event,
895 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
896 stats->rxMpdu ) ||
897 nla_put_u32(vendor_event,
898 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
899 stats->txMcast ) ||
900 nla_put_u32(vendor_event,
901 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
902 stats->rxMcast ) ||
903 nla_put_u32(vendor_event,
904 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
905 stats->rxAmpdu ) ||
906 nla_put_u32(vendor_event,
907 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
908 stats->txAmpdu ) ||
909 nla_put_u32(vendor_event,
910 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
911 stats->mpduLost )||
912 nla_put_u32(vendor_event,
913 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
914 stats->retries ) ||
915 nla_put_u32(vendor_event,
916 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
917 stats->retriesShort ) ||
918 nla_put_u32(vendor_event,
919 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
920 stats->retriesLong ) ||
921 nla_put_u32(vendor_event,
922 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
923 stats->contentionTimeMin ) ||
924 nla_put_u32(vendor_event,
925 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
926 stats->contentionTimeMax ) ||
927 nla_put_u32(vendor_event,
928 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
929 stats->contentionTimeAvg ) ||
930 nla_put_u32(vendor_event,
931 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
932 stats->contentionNumSamples ))
933 {
934 hddLog(VOS_TRACE_LEVEL_ERROR,
935 FL("QCA_WLAN_VENDOR_ATTR put fail") );
936 return FALSE;
937 }
938 return TRUE;
939}
940
941static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
942 struct sk_buff *vendor_event)
943{
Dino Myclec8f3f332014-07-21 16:48:27 +0530944 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530945 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
946 nla_put(vendor_event,
947 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
948 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
949 nla_put_u32(vendor_event,
950 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
951 stats->state ) ||
952 nla_put_u32(vendor_event,
953 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
954 stats->roaming ) ||
955 nla_put_u32(vendor_event,
956 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
957 stats->capabilities ) ||
958 nla_put(vendor_event,
959 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
960 strlen(stats->ssid), stats->ssid) ||
961 nla_put(vendor_event,
962 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
963 WNI_CFG_BSSID_LEN, stats->bssid) ||
964 nla_put(vendor_event,
965 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
966 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
967 nla_put(vendor_event,
968 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
969 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
970 )
971 {
972 hddLog(VOS_TRACE_LEVEL_ERROR,
973 FL("QCA_WLAN_VENDOR_ATTR put fail") );
974 return FALSE;
975 }
976 return TRUE;
977}
978
Dino Mycle3b9536d2014-07-09 22:05:24 +0530979static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
980 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530981 struct sk_buff *vendor_event)
982{
983 int i = 0;
984 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530985 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
986 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530987 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530988
Sunil Duttc69bccb2014-05-26 21:30:20 +0530989 if (FALSE == put_wifi_interface_info(
990 &pWifiIfaceStat->info,
991 vendor_event))
992 {
993 hddLog(VOS_TRACE_LEVEL_ERROR,
994 FL("QCA_WLAN_VENDOR_ATTR put fail") );
995 return FALSE;
996
997 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530998 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
999 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
1000 if (NULL == pWifiIfaceStatTL)
1001 {
1002 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1003 return FALSE;
1004 }
1005
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301006 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1007 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1008 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1009 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1010
1011 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1012 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1013 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1014 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301015
1016 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1017 {
1018 if (VOS_STATUS_SUCCESS ==
1019 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1020 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1021 {
1022 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1023 * obtained from TL structure
1024 */
1025
1026 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1027 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301028 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1029
Srinivas Dasari98947432014-11-07 19:41:24 +05301030 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1031 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1032 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1033 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1034 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1035 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1036 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1037 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301038
Srinivas Dasari98947432014-11-07 19:41:24 +05301039 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1040 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1041 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1042 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1043 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1044 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1045 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1046 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301047
Srinivas Dasari98947432014-11-07 19:41:24 +05301048 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1049 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1050 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1051 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1052 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1053 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1054 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1055 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301056 }
1057 else
1058 {
1059 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1060 }
1061
Dino Mycle3b9536d2014-07-09 22:05:24 +05301062 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1063 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1064 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1065 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1066 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1067 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1068 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1069 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1070 }
1071 else
1072 {
1073 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1074 }
1075
1076
Sunil Duttc69bccb2014-05-26 21:30:20 +05301077
1078 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301079 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1080 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1081 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301082 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1083 pWifiIfaceStat->beaconRx) ||
1084 nla_put_u32(vendor_event,
1085 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1086 pWifiIfaceStat->mgmtRx) ||
1087 nla_put_u32(vendor_event,
1088 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1089 pWifiIfaceStat->mgmtActionRx) ||
1090 nla_put_u32(vendor_event,
1091 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1092 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301093 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301094 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1095 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301096 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301097 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1098 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301099 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301100 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1101 pWifiIfaceStat->rssiAck))
1102 {
1103 hddLog(VOS_TRACE_LEVEL_ERROR,
1104 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301105 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301106 return FALSE;
1107 }
1108
1109 wmmInfo = nla_nest_start(vendor_event,
1110 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301111 if(!wmmInfo)
1112 {
1113 vos_mem_free(pWifiIfaceStatTL);
1114 return FALSE;
1115 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301116 for (i = 0; i < WIFI_AC_MAX; i++)
1117 {
1118 struct nlattr *wmmStats;
1119 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301120 if(!wmmStats)
1121 {
1122 vos_mem_free(pWifiIfaceStatTL);
1123 return FALSE;
1124 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301125 if (FALSE == put_wifi_wmm_ac_stat(
1126 &pWifiIfaceStat->AccessclassStats[i],
1127 vendor_event))
1128 {
1129 hddLog(VOS_TRACE_LEVEL_ERROR,
1130 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301131 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301132 return FALSE;
1133 }
1134
1135 nla_nest_end(vendor_event, wmmStats);
1136 }
1137 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301138 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301139 return TRUE;
1140}
1141
1142static tSirWifiInterfaceMode
1143 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1144{
1145 switch (deviceMode)
1146 {
1147 case WLAN_HDD_INFRA_STATION:
1148 return WIFI_INTERFACE_STA;
1149 case WLAN_HDD_SOFTAP:
1150 return WIFI_INTERFACE_SOFTAP;
1151 case WLAN_HDD_P2P_CLIENT:
1152 return WIFI_INTERFACE_P2P_CLIENT;
1153 case WLAN_HDD_P2P_GO:
1154 return WIFI_INTERFACE_P2P_GO;
1155 case WLAN_HDD_IBSS:
1156 return WIFI_INTERFACE_IBSS;
1157 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301158 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301159 }
1160}
1161
1162static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1163 tpSirWifiInterfaceInfo pInfo)
1164{
1165 v_U8_t *staMac = NULL;
1166 hdd_station_ctx_t *pHddStaCtx;
1167 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1168 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1169
1170 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1171
1172 vos_mem_copy(pInfo->macAddr,
1173 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1174
1175 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1176 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1177 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1178 {
1179 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1180 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1181 {
1182 pInfo->state = WIFI_DISCONNECTED;
1183 }
1184 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1185 {
1186 hddLog(VOS_TRACE_LEVEL_ERROR,
1187 "%s: Session ID %d, Connection is in progress", __func__,
1188 pAdapter->sessionId);
1189 pInfo->state = WIFI_ASSOCIATING;
1190 }
1191 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1192 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1193 {
1194 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1195 hddLog(VOS_TRACE_LEVEL_ERROR,
1196 "%s: client " MAC_ADDRESS_STR
1197 " is in the middle of WPS/EAPOL exchange.", __func__,
1198 MAC_ADDR_ARRAY(staMac));
1199 pInfo->state = WIFI_AUTHENTICATING;
1200 }
1201 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1202 {
1203 pInfo->state = WIFI_ASSOCIATED;
1204 vos_mem_copy(pInfo->bssid,
1205 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1206 vos_mem_copy(pInfo->ssid,
1207 pHddStaCtx->conn_info.SSID.SSID.ssId,
1208 pHddStaCtx->conn_info.SSID.SSID.length);
1209 //NULL Terminate the string.
1210 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1211 }
1212 }
1213 vos_mem_copy(pInfo->countryStr,
1214 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1215
1216 vos_mem_copy(pInfo->apCountryStr,
1217 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1218
1219 return TRUE;
1220}
1221
1222/*
1223 * hdd_link_layer_process_peer_stats () - This function is called after
1224 * receiving Link Layer Peer statistics from FW.This function converts
1225 * the firmware data to the NL data and sends the same to the kernel/upper
1226 * layers.
1227 */
1228static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1229 v_VOID_t *pData)
1230{
1231 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301232 tpSirWifiPeerStat pWifiPeerStat;
1233 tpSirWifiPeerInfo pWifiPeerInfo;
1234 struct nlattr *peerInfo;
1235 struct sk_buff *vendor_event;
1236 int status, i;
1237
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301238 ENTER();
1239
Sunil Duttc69bccb2014-05-26 21:30:20 +05301240 status = wlan_hdd_validate_context(pHddCtx);
1241 if (0 != status)
1242 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301243 return;
1244 }
1245
1246 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1247
1248 hddLog(VOS_TRACE_LEVEL_INFO,
1249 "LL_STATS_PEER_ALL : numPeers %u",
1250 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301251 /*
1252 * Allocate a size of 4096 for the peer stats comprising
1253 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1254 * sizeof (tSirWifiRateStat).Each field is put with an
1255 * NL attribute.The size of 4096 is considered assuming
1256 * that number of rates shall not exceed beyond 50 with
1257 * the sizeof (tSirWifiRateStat) being 32.
1258 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301259 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1260 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301261 if (!vendor_event)
1262 {
1263 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301264 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301265 __func__);
1266 return;
1267 }
1268 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301269 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1270 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1271 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301272 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1273 pWifiPeerStat->numPeers))
1274 {
1275 hddLog(VOS_TRACE_LEVEL_ERROR,
1276 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1277 kfree_skb(vendor_event);
1278 return;
1279 }
1280
1281 peerInfo = nla_nest_start(vendor_event,
1282 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301283 if(!peerInfo)
1284 {
1285 hddLog(VOS_TRACE_LEVEL_ERROR,
1286 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1287 __func__);
1288 kfree_skb(vendor_event);
1289 return;
1290 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301291
1292 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1293 pWifiPeerStat->peerInfo);
1294
1295 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1296 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301297 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301298 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301299
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301300 if(!peers)
1301 {
1302 hddLog(VOS_TRACE_LEVEL_ERROR,
1303 "%s: peer stats put fail",
1304 __func__);
1305 kfree_skb(vendor_event);
1306 return;
1307 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301308 if (FALSE == put_wifi_peer_info(
1309 pWifiPeerInfo, vendor_event))
1310 {
1311 hddLog(VOS_TRACE_LEVEL_ERROR,
1312 "%s: put_wifi_peer_info put fail", __func__);
1313 kfree_skb(vendor_event);
1314 return;
1315 }
1316
1317 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1318 pWifiPeerStat->peerInfo +
1319 (i * sizeof(tSirWifiPeerInfo)) +
1320 (numRate * sizeof (tSirWifiRateStat)));
1321 nla_nest_end(vendor_event, peers);
1322 }
1323 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301324 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301325 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301326}
1327
1328/*
1329 * hdd_link_layer_process_iface_stats () - This function is called after
1330 * receiving Link Layer Interface statistics from FW.This function converts
1331 * the firmware data to the NL data and sends the same to the kernel/upper
1332 * layers.
1333 */
1334static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1335 v_VOID_t *pData)
1336{
1337 tpSirWifiIfaceStat pWifiIfaceStat;
1338 struct sk_buff *vendor_event;
1339 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1340 int status;
1341
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301342 ENTER();
1343
Sunil Duttc69bccb2014-05-26 21:30:20 +05301344 status = wlan_hdd_validate_context(pHddCtx);
1345 if (0 != status)
1346 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301347 return;
1348 }
1349 /*
1350 * Allocate a size of 4096 for the interface stats comprising
1351 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1352 * assuming that all these fit with in the limit.Please take
1353 * a call on the limit based on the data requirements on
1354 * interface statistics.
1355 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301356 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1357 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301358 if (!vendor_event)
1359 {
1360 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301361 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301362 return;
1363 }
1364
1365 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1366
Dino Mycle3b9536d2014-07-09 22:05:24 +05301367
1368 if (FALSE == hdd_get_interface_info( pAdapter,
1369 &pWifiIfaceStat->info))
1370 {
1371 hddLog(VOS_TRACE_LEVEL_ERROR,
1372 FL("hdd_get_interface_info get fail") );
1373 kfree_skb(vendor_event);
1374 return;
1375 }
1376
1377 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1378 vendor_event))
1379 {
1380 hddLog(VOS_TRACE_LEVEL_ERROR,
1381 FL("put_wifi_iface_stats fail") );
1382 kfree_skb(vendor_event);
1383 return;
1384 }
1385
Sunil Duttc69bccb2014-05-26 21:30:20 +05301386 hddLog(VOS_TRACE_LEVEL_INFO,
1387 "WMI_LINK_STATS_IFACE Data");
1388
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301389 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301390
1391 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301392}
1393
1394/*
1395 * hdd_link_layer_process_radio_stats () - This function is called after
1396 * receiving Link Layer Radio statistics from FW.This function converts
1397 * the firmware data to the NL data and sends the same to the kernel/upper
1398 * layers.
1399 */
1400static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1401 v_VOID_t *pData)
1402{
1403 int status, i;
1404 tpSirWifiRadioStat pWifiRadioStat;
1405 tpSirWifiChannelStats pWifiChannelStats;
1406 struct sk_buff *vendor_event;
1407 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1408 struct nlattr *chList;
1409
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301410 ENTER();
1411
Sunil Duttc69bccb2014-05-26 21:30:20 +05301412 status = wlan_hdd_validate_context(pHddCtx);
1413 if (0 != status)
1414 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301415 return;
1416 }
1417 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1418
1419 hddLog(VOS_TRACE_LEVEL_INFO,
1420 "LL_STATS_RADIO"
1421 " radio is %d onTime is %u "
1422 " txTime is %u rxTime is %u "
1423 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301424 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301425 " onTimePnoScan is %u onTimeHs20 is %u "
1426 " numChannels is %u",
1427 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1428 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1429 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301430 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301431 pWifiRadioStat->onTimeRoamScan,
1432 pWifiRadioStat->onTimePnoScan,
1433 pWifiRadioStat->onTimeHs20,
1434 pWifiRadioStat->numChannels);
1435 /*
1436 * Allocate a size of 4096 for the Radio stats comprising
1437 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1438 * (tSirWifiChannelStats).Each channel data is put with an
1439 * NL attribute.The size of 4096 is considered assuming that
1440 * number of channels shall not exceed beyond 60 with the
1441 * sizeof (tSirWifiChannelStats) being 24 bytes.
1442 */
1443
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301444 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1445 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301446 if (!vendor_event)
1447 {
1448 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301449 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301450 return;
1451 }
1452
1453 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301454 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1455 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1456 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301457 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1458 pWifiRadioStat->radio) ||
1459 nla_put_u32(vendor_event,
1460 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1461 pWifiRadioStat->onTime) ||
1462 nla_put_u32(vendor_event,
1463 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1464 pWifiRadioStat->txTime) ||
1465 nla_put_u32(vendor_event,
1466 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1467 pWifiRadioStat->rxTime) ||
1468 nla_put_u32(vendor_event,
1469 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1470 pWifiRadioStat->onTimeScan) ||
1471 nla_put_u32(vendor_event,
1472 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1473 pWifiRadioStat->onTimeNbd) ||
1474 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301475 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1476 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301477 nla_put_u32(vendor_event,
1478 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1479 pWifiRadioStat->onTimeRoamScan) ||
1480 nla_put_u32(vendor_event,
1481 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1482 pWifiRadioStat->onTimePnoScan) ||
1483 nla_put_u32(vendor_event,
1484 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1485 pWifiRadioStat->onTimeHs20) ||
1486 nla_put_u32(vendor_event,
1487 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1488 pWifiRadioStat->numChannels))
1489 {
1490 hddLog(VOS_TRACE_LEVEL_ERROR,
1491 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1492 kfree_skb(vendor_event);
1493 return ;
1494 }
1495
1496 chList = nla_nest_start(vendor_event,
1497 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301498 if(!chList)
1499 {
1500 hddLog(VOS_TRACE_LEVEL_ERROR,
1501 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1502 __func__);
1503 kfree_skb(vendor_event);
1504 return;
1505 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301506 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1507 {
1508 struct nlattr *chInfo;
1509
1510 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1511 pWifiRadioStat->channels +
1512 (i * sizeof(tSirWifiChannelStats)));
1513
Sunil Duttc69bccb2014-05-26 21:30:20 +05301514 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301515 if(!chInfo)
1516 {
1517 hddLog(VOS_TRACE_LEVEL_ERROR,
1518 "%s: failed to put chInfo",
1519 __func__);
1520 kfree_skb(vendor_event);
1521 return;
1522 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301523
1524 if (nla_put_u32(vendor_event,
1525 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1526 pWifiChannelStats->channel.width) ||
1527 nla_put_u32(vendor_event,
1528 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1529 pWifiChannelStats->channel.centerFreq) ||
1530 nla_put_u32(vendor_event,
1531 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1532 pWifiChannelStats->channel.centerFreq0) ||
1533 nla_put_u32(vendor_event,
1534 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1535 pWifiChannelStats->channel.centerFreq1) ||
1536 nla_put_u32(vendor_event,
1537 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1538 pWifiChannelStats->onTime) ||
1539 nla_put_u32(vendor_event,
1540 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1541 pWifiChannelStats->ccaBusyTime))
1542 {
1543 hddLog(VOS_TRACE_LEVEL_ERROR,
1544 FL("cfg80211_vendor_event_alloc failed") );
1545 kfree_skb(vendor_event);
1546 return ;
1547 }
1548 nla_nest_end(vendor_event, chInfo);
1549 }
1550 nla_nest_end(vendor_event, chList);
1551
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301552 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301553
1554 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301555 return;
1556}
1557
1558/*
1559 * hdd_link_layer_stats_ind_callback () - This function is called after
1560 * receiving Link Layer indications from FW.This callback converts the firmware
1561 * data to the NL data and send the same to the kernel/upper layers.
1562 */
1563static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1564 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301565 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301566{
Dino Mycled3d50022014-07-07 12:58:25 +05301567 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1568 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301569 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301570 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301571 int status;
1572
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301573 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301574
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301575 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301576 if (0 != status)
1577 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301578 return;
1579 }
1580
Dino Mycled3d50022014-07-07 12:58:25 +05301581 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1582 if (NULL == pAdapter)
1583 {
1584 hddLog(VOS_TRACE_LEVEL_ERROR,
1585 FL(" MAC address %pM does not exist with host"),
1586 macAddr);
1587 return;
1588 }
1589
Sunil Duttc69bccb2014-05-26 21:30:20 +05301590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301591 "%s: Interface: %s LLStats indType: %d", __func__,
1592 pAdapter->dev->name, indType);
1593
Sunil Duttc69bccb2014-05-26 21:30:20 +05301594 switch (indType)
1595 {
1596 case SIR_HAL_LL_STATS_RESULTS_RSP:
1597 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301598 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301599 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1600 "respId = %u, moreResultToFollow = %u",
1601 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1602 macAddr, linkLayerStatsResults->respId,
1603 linkLayerStatsResults->moreResultToFollow);
1604
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301605 spin_lock(&hdd_context_lock);
1606 context = &pHddCtx->ll_stats_context;
1607 /* validate response received from target */
1608 if ((context->request_id != linkLayerStatsResults->respId) ||
1609 !(context->request_bitmap & linkLayerStatsResults->paramId))
1610 {
1611 spin_unlock(&hdd_context_lock);
1612 hddLog(LOGE,
1613 FL("Error : Request id %d response id %d request bitmap 0x%x"
1614 "response bitmap 0x%x"),
1615 context->request_id, linkLayerStatsResults->respId,
1616 context->request_bitmap, linkLayerStatsResults->paramId);
1617 return;
1618 }
1619 spin_unlock(&hdd_context_lock);
1620
Sunil Duttc69bccb2014-05-26 21:30:20 +05301621 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1622 {
1623 hdd_link_layer_process_radio_stats(pAdapter,
1624 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301625 spin_lock(&hdd_context_lock);
1626 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1627 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301628 }
1629 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1630 {
1631 hdd_link_layer_process_iface_stats(pAdapter,
1632 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301633 spin_lock(&hdd_context_lock);
1634 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1635 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301636 }
1637 else if ( linkLayerStatsResults->paramId &
1638 WMI_LINK_STATS_ALL_PEER )
1639 {
1640 hdd_link_layer_process_peer_stats(pAdapter,
1641 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301642 spin_lock(&hdd_context_lock);
1643 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1644 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301645 } /* WMI_LINK_STATS_ALL_PEER */
1646 else
1647 {
1648 hddLog(VOS_TRACE_LEVEL_ERROR,
1649 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1650 }
1651
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301652 spin_lock(&hdd_context_lock);
1653 /* complete response event if all requests are completed */
1654 if (0 == context->request_bitmap)
1655 complete(&context->response_event);
1656 spin_unlock(&hdd_context_lock);
1657
Sunil Duttc69bccb2014-05-26 21:30:20 +05301658 break;
1659 }
1660 default:
1661 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1662 break;
1663 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301664
1665 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301666 return;
1667}
1668
1669const struct
1670nla_policy
1671qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1672{
1673 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1674 { .type = NLA_U32 },
1675 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1676 { .type = NLA_U32 },
1677};
1678
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301679static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1680 struct wireless_dev *wdev,
1681 const void *data,
1682 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301683{
1684 int status;
1685 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301686 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301687 struct net_device *dev = wdev->netdev;
1688 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1689 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1690
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301691 ENTER();
1692
Sunil Duttc69bccb2014-05-26 21:30:20 +05301693 status = wlan_hdd_validate_context(pHddCtx);
1694 if (0 != status)
1695 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301696 return -EINVAL;
1697 }
1698
1699 if (NULL == pAdapter)
1700 {
1701 hddLog(VOS_TRACE_LEVEL_ERROR,
1702 FL("HDD adapter is Null"));
1703 return -ENODEV;
1704 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301705 /* check the LLStats Capability */
1706 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1707 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1708 {
1709 hddLog(VOS_TRACE_LEVEL_ERROR,
1710 FL("Link Layer Statistics not supported by Firmware"));
1711 return -EINVAL;
1712 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301713
1714 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1715 (struct nlattr *)data,
1716 data_len, qca_wlan_vendor_ll_set_policy))
1717 {
1718 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1719 return -EINVAL;
1720 }
1721 if (!tb_vendor
1722 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1723 {
1724 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1725 return -EINVAL;
1726 }
1727 if (!tb_vendor[
1728 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1729 {
1730 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1731 return -EINVAL;
1732 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301733 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301734 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301735
Dino Mycledf0a5d92014-07-04 09:41:55 +05301736 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301737 nla_get_u32(
1738 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1739
Dino Mycledf0a5d92014-07-04 09:41:55 +05301740 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301741 nla_get_u32(
1742 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1743
Dino Mycled3d50022014-07-07 12:58:25 +05301744 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1745 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301746
1747
1748 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301749 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1750 "Statistics Gathering = %d ",
1751 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1752 linkLayerStatsSetReq.mpduSizeThreshold,
1753 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301754
1755 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1756 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301757 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301758 {
1759 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1760 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301761 return -EINVAL;
1762
1763 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301764
Sunil Duttc69bccb2014-05-26 21:30:20 +05301765 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301766 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301767 {
1768 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1769 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301770 return -EINVAL;
1771 }
1772
1773 pAdapter->isLinkLayerStatsSet = 1;
1774
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301775 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301776 return 0;
1777}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301778static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1779 struct wireless_dev *wdev,
1780 const void *data,
1781 int data_len)
1782{
1783 int ret = 0;
1784
1785 vos_ssr_protect(__func__);
1786 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1787 vos_ssr_unprotect(__func__);
1788
1789 return ret;
1790}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301791
1792const struct
1793nla_policy
1794qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1795{
1796 /* Unsigned 32bit value provided by the caller issuing the GET stats
1797 * command. When reporting
1798 * the stats results, the driver uses the same value to indicate
1799 * which GET request the results
1800 * correspond to.
1801 */
1802 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1803
1804 /* Unsigned 32bit value . bit mask to identify what statistics are
1805 requested for retrieval */
1806 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1807};
1808
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301809static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1810 struct wireless_dev *wdev,
1811 const void *data,
1812 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301813{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301814 unsigned long rc;
1815 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301816 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1817 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301818 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301819 struct net_device *dev = wdev->netdev;
1820 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301821 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301822 int status;
1823
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301824 ENTER();
1825
Sunil Duttc69bccb2014-05-26 21:30:20 +05301826 status = wlan_hdd_validate_context(pHddCtx);
1827 if (0 != status)
1828 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301829 return -EINVAL ;
1830 }
1831
1832 if (NULL == pAdapter)
1833 {
1834 hddLog(VOS_TRACE_LEVEL_FATAL,
1835 "%s: HDD adapter is Null", __func__);
1836 return -ENODEV;
1837 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301838
1839 if (pHddStaCtx == NULL)
1840 {
1841 hddLog(VOS_TRACE_LEVEL_FATAL,
1842 "%s: HddStaCtx is Null", __func__);
1843 return -ENODEV;
1844 }
1845
Dino Mycledf0a5d92014-07-04 09:41:55 +05301846 /* check the LLStats Capability */
1847 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1848 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1849 {
1850 hddLog(VOS_TRACE_LEVEL_ERROR,
1851 FL("Link Layer Statistics not supported by Firmware"));
1852 return -EINVAL;
1853 }
1854
Sunil Duttc69bccb2014-05-26 21:30:20 +05301855
1856 if (!pAdapter->isLinkLayerStatsSet)
1857 {
1858 hddLog(VOS_TRACE_LEVEL_FATAL,
1859 "%s: isLinkLayerStatsSet : %d",
1860 __func__, pAdapter->isLinkLayerStatsSet);
1861 return -EINVAL;
1862 }
1863
Mukul Sharma10313ba2015-07-29 19:14:39 +05301864 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1865 {
1866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1867 "%s: Roaming in progress, so unable to proceed this request", __func__);
1868 return -EBUSY;
1869 }
1870
Sunil Duttc69bccb2014-05-26 21:30:20 +05301871 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1872 (struct nlattr *)data,
1873 data_len, qca_wlan_vendor_ll_get_policy))
1874 {
1875 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1876 return -EINVAL;
1877 }
1878
1879 if (!tb_vendor
1880 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1881 {
1882 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1883 return -EINVAL;
1884 }
1885
1886 if (!tb_vendor
1887 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1888 {
1889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1890 return -EINVAL;
1891 }
1892
Sunil Duttc69bccb2014-05-26 21:30:20 +05301893
Dino Mycledf0a5d92014-07-04 09:41:55 +05301894 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301895 nla_get_u32( tb_vendor[
1896 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301897 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301898 nla_get_u32( tb_vendor[
1899 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1900
Dino Mycled3d50022014-07-07 12:58:25 +05301901 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1902 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301903
1904 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301905 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1906 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301907 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301908
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301909 spin_lock(&hdd_context_lock);
1910 context = &pHddCtx->ll_stats_context;
1911 context->request_id = linkLayerStatsGetReq.reqId;
1912 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1913 INIT_COMPLETION(context->response_event);
1914 spin_unlock(&hdd_context_lock);
1915
Sunil Duttc69bccb2014-05-26 21:30:20 +05301916 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301917 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301918 {
1919 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1920 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301921 return -EINVAL;
1922 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301923
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301924 rc = wait_for_completion_timeout(&context->response_event,
1925 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1926 if (!rc)
1927 {
1928 hddLog(LOGE,
1929 FL("Target response timed out request id %d request bitmap 0x%x"),
1930 context->request_id, context->request_bitmap);
1931 return -ETIMEDOUT;
1932 }
1933
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301934 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301935 return 0;
1936}
1937
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301938static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1939 struct wireless_dev *wdev,
1940 const void *data,
1941 int data_len)
1942{
1943 int ret = 0;
1944
1945 vos_ssr_protect(__func__);
1946 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1947 vos_ssr_unprotect(__func__);
1948
1949 return ret;
1950}
1951
Sunil Duttc69bccb2014-05-26 21:30:20 +05301952const struct
1953nla_policy
1954qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1955{
1956 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1957 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1958 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1959 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1960};
1961
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301962static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1963 struct wireless_dev *wdev,
1964 const void *data,
1965 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301966{
1967 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1968 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301969 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301970 struct net_device *dev = wdev->netdev;
1971 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1972 u32 statsClearReqMask;
1973 u8 stopReq;
1974 int status;
1975
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301976 ENTER();
1977
Sunil Duttc69bccb2014-05-26 21:30:20 +05301978 status = wlan_hdd_validate_context(pHddCtx);
1979 if (0 != status)
1980 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301981 return -EINVAL;
1982 }
1983
1984 if (NULL == pAdapter)
1985 {
1986 hddLog(VOS_TRACE_LEVEL_FATAL,
1987 "%s: HDD adapter is Null", __func__);
1988 return -ENODEV;
1989 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301990 /* check the LLStats Capability */
1991 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1992 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1993 {
1994 hddLog(VOS_TRACE_LEVEL_ERROR,
1995 FL("Enable LLStats Capability"));
1996 return -EINVAL;
1997 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301998
1999 if (!pAdapter->isLinkLayerStatsSet)
2000 {
2001 hddLog(VOS_TRACE_LEVEL_FATAL,
2002 "%s: isLinkLayerStatsSet : %d",
2003 __func__, pAdapter->isLinkLayerStatsSet);
2004 return -EINVAL;
2005 }
2006
2007 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2008 (struct nlattr *)data,
2009 data_len, qca_wlan_vendor_ll_clr_policy))
2010 {
2011 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2012 return -EINVAL;
2013 }
2014
2015 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2016
2017 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2018 {
2019 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2020 return -EINVAL;
2021
2022 }
2023
Sunil Duttc69bccb2014-05-26 21:30:20 +05302024
Dino Mycledf0a5d92014-07-04 09:41:55 +05302025 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302026 nla_get_u32(
2027 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2028
Dino Mycledf0a5d92014-07-04 09:41:55 +05302029 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302030 nla_get_u8(
2031 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2032
2033 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302034 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302035
Dino Mycled3d50022014-07-07 12:58:25 +05302036 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2037 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302038
2039 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302040 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2041 "statsClearReqMask = 0x%X, stopReq = %d",
2042 linkLayerStatsClearReq.reqId,
2043 linkLayerStatsClearReq.macAddr,
2044 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302045 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302046
2047 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302048 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302049 {
2050 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302051 hdd_station_ctx_t *pHddStaCtx;
2052
2053 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2054 if (VOS_STATUS_SUCCESS !=
2055 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2056 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2057 {
2058 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2059 "WLANTL_ClearInterfaceStats Failed", __func__);
2060 return -EINVAL;
2061 }
2062 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2063 (statsClearReqMask & WIFI_STATS_IFACE)) {
2064 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2065 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2066 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2067 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2068 }
2069
Sunil Duttc69bccb2014-05-26 21:30:20 +05302070 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2071 2 * sizeof(u32) +
2072 NLMSG_HDRLEN);
2073
2074 if (temp_skbuff != NULL)
2075 {
2076
2077 if (nla_put_u32(temp_skbuff,
2078 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2079 statsClearReqMask) ||
2080 nla_put_u32(temp_skbuff,
2081 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2082 stopReq))
2083 {
2084 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2085 kfree_skb(temp_skbuff);
2086 return -EINVAL;
2087 }
2088 /* If the ask is to stop the stats collection as part of clear
2089 * (stopReq = 1) , ensure that no further requests of get
2090 * go to the firmware by having isLinkLayerStatsSet set to 0.
2091 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302092 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302093 * case the firmware is just asked to clear the statistics.
2094 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302095 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302096 pAdapter->isLinkLayerStatsSet = 0;
2097 return cfg80211_vendor_cmd_reply(temp_skbuff);
2098 }
2099 return -ENOMEM;
2100 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302101
2102 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302103 return -EINVAL;
2104}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302105static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2106 struct wireless_dev *wdev,
2107 const void *data,
2108 int data_len)
2109{
2110 int ret = 0;
2111
2112 vos_ssr_protect(__func__);
2113 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2114 vos_ssr_unprotect(__func__);
2115
2116 return ret;
2117
2118
2119}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302120#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2121
Dino Mycle6fb96c12014-06-10 11:52:40 +05302122#ifdef WLAN_FEATURE_EXTSCAN
2123static const struct nla_policy
2124wlan_hdd_extscan_config_policy
2125 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2126{
2127 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2128 { .type = NLA_U32 },
2129 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2130 { .type = NLA_U32 },
2131 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2132 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2133 { .type = NLA_U32 },
2134 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2135 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2136
2137 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2138 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2139 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2140 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2141 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302142 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2143 { .type = NLA_U32 },
2144 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2145 { .type = NLA_U32 },
2146 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2147 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302148 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2149 { .type = NLA_U32 },
2150 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2151 { .type = NLA_U32 },
2152 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2153 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302154 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2155 { .type = NLA_U8 },
2156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302157 { .type = NLA_U8 },
2158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2159 { .type = NLA_U8 },
2160 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2161 { .type = NLA_U8 },
2162
2163 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2164 { .type = NLA_U32 },
2165 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2166 { .type = NLA_UNSPEC },
2167 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2168 { .type = NLA_S32 },
2169 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2170 { .type = NLA_S32 },
2171 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2172 { .type = NLA_U32 },
2173 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2174 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302175 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2176 { .type = NLA_U32 },
2177 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2178 { .type = NLA_BINARY,
2179 .len = IEEE80211_MAX_SSID_LEN + 1 },
2180 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302181 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302182 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2183 { .type = NLA_U32 },
2184 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2185 { .type = NLA_U8 },
2186 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2187 { .type = NLA_S32 },
2188 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2189 { .type = NLA_S32 },
2190 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2191 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302192};
2193
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302194/**
2195 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2196 * @ctx: hdd global context
2197 * @data: capabilities data
2198 *
2199 * Return: none
2200 */
2201static void
2202wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302203{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302204 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302205 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302206 tSirEXTScanCapabilitiesEvent *data =
2207 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302208
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302209 ENTER();
2210
2211 if (wlan_hdd_validate_context(pHddCtx))
2212 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302213 return;
2214 }
2215
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302216 if (!pMsg)
2217 {
2218 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2219 return;
2220 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302221
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302222 vos_spin_lock_acquire(&hdd_context_lock);
2223
2224 context = &pHddCtx->ext_scan_context;
2225 /* validate response received from target*/
2226 if (context->request_id != data->requestId)
2227 {
2228 vos_spin_lock_release(&hdd_context_lock);
2229 hddLog(LOGE,
2230 FL("Target response id did not match: request_id %d resposne_id %d"),
2231 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302232 return;
2233 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302234 else
2235 {
2236 context->capability_response = *data;
2237 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302238 }
2239
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302240 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302241
Dino Mycle6fb96c12014-06-10 11:52:40 +05302242 return;
2243}
2244
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302245/*
2246 * define short names for the global vendor params
2247 * used by wlan_hdd_send_ext_scan_capability()
2248 */
2249#define PARAM_REQUEST_ID \
2250 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2251#define PARAM_STATUS \
2252 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2253#define MAX_SCAN_CACHE_SIZE \
2254 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2255#define MAX_SCAN_BUCKETS \
2256 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2257#define MAX_AP_CACHE_PER_SCAN \
2258 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2259#define MAX_RSSI_SAMPLE_SIZE \
2260 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2261#define MAX_SCAN_RPT_THRHOLD \
2262 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2263#define MAX_HOTLIST_BSSIDS \
2264 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2265#define MAX_BSSID_HISTORY_ENTRIES \
2266 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2267#define MAX_HOTLIST_SSIDS \
2268 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302269#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2270 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302271
2272static int wlan_hdd_send_ext_scan_capability(void *ctx)
2273{
2274 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2275 struct sk_buff *skb = NULL;
2276 int ret;
2277 tSirEXTScanCapabilitiesEvent *data;
2278 tANI_U32 nl_buf_len;
2279
2280 ret = wlan_hdd_validate_context(pHddCtx);
2281 if (0 != ret)
2282 {
2283 return ret;
2284 }
2285
2286 data = &(pHddCtx->ext_scan_context.capability_response);
2287
2288 nl_buf_len = NLMSG_HDRLEN;
2289 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2290 (sizeof(data->status) + NLA_HDRLEN) +
2291 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2292 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2293 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2294 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2295 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2296 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2297 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2298 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2299
2300 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2301
2302 if (!skb)
2303 {
2304 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2305 return -ENOMEM;
2306 }
2307
2308 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2309 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2310 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2311 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2312 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2313 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2314 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2315 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2316
2317 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2318 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2319 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2320 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2321 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2322 data->maxApPerScan) ||
2323 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2324 data->maxRssiSampleSize) ||
2325 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2326 data->maxScanReportingThreshold) ||
2327 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2328 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2329 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302330 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2331 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302332 {
2333 hddLog(LOGE, FL("nla put fail"));
2334 goto nla_put_failure;
2335 }
2336
2337 cfg80211_vendor_cmd_reply(skb);
2338 return 0;
2339
2340nla_put_failure:
2341 kfree_skb(skb);
2342 return -EINVAL;;
2343}
2344
2345/*
2346 * done with short names for the global vendor params
2347 * used by wlan_hdd_send_ext_scan_capability()
2348 */
2349#undef PARAM_REQUEST_ID
2350#undef PARAM_STATUS
2351#undef MAX_SCAN_CACHE_SIZE
2352#undef MAX_SCAN_BUCKETS
2353#undef MAX_AP_CACHE_PER_SCAN
2354#undef MAX_RSSI_SAMPLE_SIZE
2355#undef MAX_SCAN_RPT_THRHOLD
2356#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302357#undef MAX_BSSID_HISTORY_ENTRIES
2358#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302359
2360static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2361{
2362 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2363 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302364 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302365 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302366
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302367 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302368
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302369 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302370 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302371
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302372 if (!pMsg)
2373 {
2374 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302375 return;
2376 }
2377
Dino Mycle6fb96c12014-06-10 11:52:40 +05302378 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2379 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2380
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302381 context = &pHddCtx->ext_scan_context;
2382 spin_lock(&hdd_context_lock);
2383 if (context->request_id == pData->requestId) {
2384 context->response_status = pData->status ? -EINVAL : 0;
2385 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302386 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302387 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302388
2389 /*
2390 * Store the Request ID for comparing with the requestID obtained
2391 * in other requests.HDD shall return a failure is the extscan_stop
2392 * request is issued with a different requestId as that of the
2393 * extscan_start request. Also, This requestId shall be used while
2394 * indicating the full scan results to the upper layers.
2395 * The requestId is stored with the assumption that the firmware
2396 * shall return the ext scan start request's requestId in ext scan
2397 * start response.
2398 */
2399 if (pData->status == 0)
2400 pMac->sme.extScanStartReqId = pData->requestId;
2401
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302402 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302403 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302404}
2405
2406
2407static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2408{
2409 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2410 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302411 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302412
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302413 ENTER();
2414
2415 if (wlan_hdd_validate_context(pHddCtx)){
2416 return;
2417 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302418
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302419 if (!pMsg)
2420 {
2421 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302422 return;
2423 }
2424
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302425 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2426 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302427
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302428 context = &pHddCtx->ext_scan_context;
2429 spin_lock(&hdd_context_lock);
2430 if (context->request_id == pData->requestId) {
2431 context->response_status = pData->status ? -EINVAL : 0;
2432 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302433 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302434 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302435
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302436 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302437 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302438}
2439
Dino Mycle6fb96c12014-06-10 11:52:40 +05302440static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2441 void *pMsg)
2442{
2443 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302444 tpSirEXTScanSetBssidHotListRspParams pData =
2445 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302446 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302447
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302448 ENTER();
2449
2450 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302451 return;
2452 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302453
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302454 if (!pMsg)
2455 {
2456 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2457 return;
2458 }
2459
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302460 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2461 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302462
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302463 context = &pHddCtx->ext_scan_context;
2464 spin_lock(&hdd_context_lock);
2465 if (context->request_id == pData->requestId) {
2466 context->response_status = pData->status ? -EINVAL : 0;
2467 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302468 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302469 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302470
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302471 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302472 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302473}
2474
2475static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2476 void *pMsg)
2477{
2478 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302479 tpSirEXTScanResetBssidHotlistRspParams pData =
2480 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302481 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302482
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302483 ENTER();
2484
2485 if (wlan_hdd_validate_context(pHddCtx)) {
2486 return;
2487 }
2488 if (!pMsg)
2489 {
2490 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302491 return;
2492 }
2493
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302494 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2495 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302496
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302497 context = &pHddCtx->ext_scan_context;
2498 spin_lock(&hdd_context_lock);
2499 if (context->request_id == pData->requestId) {
2500 context->response_status = pData->status ? -EINVAL : 0;
2501 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302502 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302503 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302504
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302505 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302506 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302507}
2508
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302509static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2510 void *pMsg)
2511{
2512 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2513 tpSirEXTScanSetSsidHotListRspParams pData =
2514 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2515 struct hdd_ext_scan_context *context;
2516
2517 if (wlan_hdd_validate_context(pHddCtx)){
2518 return;
2519 }
2520
2521 if (!pMsg)
2522 {
2523 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2524 return;
2525 }
2526
2527 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2528 pData->status);
2529
2530 context = &pHddCtx->ext_scan_context;
2531 spin_lock(&hdd_context_lock);
2532 if (context->request_id == pData->requestId) {
2533 context->response_status = pData->status ? -EINVAL : 0;
2534 complete(&context->response_event);
2535 }
2536 spin_unlock(&hdd_context_lock);
2537
2538 return;
2539}
2540
2541static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2542 void *pMsg)
2543{
2544 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2545 tpSirEXTScanResetSsidHotlistRspParams pData =
2546 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2547 struct hdd_ext_scan_context *context;
2548
2549 if (wlan_hdd_validate_context(pHddCtx)) {
2550 return;
2551 }
2552 if (!pMsg)
2553 {
2554 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2555 return;
2556 }
2557
2558 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2559 pData->status);
2560
2561 context = &pHddCtx->ext_scan_context;
2562 spin_lock(&hdd_context_lock);
2563 if (context->request_id == pData->requestId) {
2564 context->response_status = pData->status ? -EINVAL : 0;
2565 complete(&context->response_event);
2566 }
2567 spin_unlock(&hdd_context_lock);
2568
2569 return;
2570}
2571
2572
Dino Mycle6fb96c12014-06-10 11:52:40 +05302573static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2574 void *pMsg)
2575{
2576 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2577 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302578 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302579 tANI_S32 totalResults;
2580 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302581 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2582 struct hdd_ext_scan_context *context;
2583 bool ignore_cached_results = false;
2584 tExtscanCachedScanResult *result;
2585 struct nlattr *nla_results;
2586 tANI_U16 ieLength= 0;
2587 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302588
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302589 ENTER();
2590
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302591 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302592 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302593
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302594 if (!pMsg)
2595 {
2596 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2597 return;
2598 }
2599
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302600 spin_lock(&hdd_context_lock);
2601 context = &pHddCtx->ext_scan_context;
2602 ignore_cached_results = context->ignore_cached_results;
2603 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302604
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302605 if (ignore_cached_results) {
2606 hddLog(LOGE,
2607 FL("Ignore the cached results received after timeout"));
2608 return;
2609 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302610
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302611 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2612 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302613
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302614 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302615
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302616 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2617 scan_id_index++) {
2618 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302619
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302620 totalResults = result->num_results;
2621 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2622 result->scan_id, result->flags, totalResults);
2623 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302624
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302625 do{
2626 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2627 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2628 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302629
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302630 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2631 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2632
2633 if (!skb) {
2634 hddLog(VOS_TRACE_LEVEL_ERROR,
2635 FL("cfg80211_vendor_event_alloc failed"));
2636 return;
2637 }
2638
2639 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2640
2641 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2642 pData->requestId) ||
2643 nla_put_u32(skb,
2644 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2645 resultsPerEvent)) {
2646 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2647 goto fail;
2648 }
2649 if (nla_put_u8(skb,
2650 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2651 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302652 {
2653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2654 goto fail;
2655 }
2656
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302657 if (nla_put_u32(skb,
2658 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2659 result->scan_id)) {
2660 hddLog(LOGE, FL("put fail"));
2661 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302662 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302663
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302664 nla_results = nla_nest_start(skb,
2665 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2666 if (!nla_results)
2667 goto fail;
2668
2669 if (resultsPerEvent) {
2670 struct nlattr *aps;
2671 struct nlattr *nla_result;
2672
2673 nla_result = nla_nest_start(skb, scan_id_index);
2674 if(!nla_result)
2675 goto fail;
2676
2677 if (nla_put_u32(skb,
2678 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2679 result->scan_id) ||
2680 nla_put_u32(skb,
2681 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2682 result->flags) ||
2683 nla_put_u32(skb,
2684 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2685 totalResults)) {
2686 hddLog(LOGE, FL("put fail"));
2687 goto fail;
2688 }
2689
2690 aps = nla_nest_start(skb,
2691 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2692 if (!aps)
2693 {
2694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2695 goto fail;
2696 }
2697
2698 head_ptr = (tpSirWifiScanResult) &(result->ap);
2699
2700 for (j = 0; j < resultsPerEvent; j++, i++) {
2701 struct nlattr *ap;
2702 pSirWifiScanResult = head_ptr + i;
2703
2704 /*
2705 * Firmware returns timestamp from WiFi turn ON till
2706 * BSSID was cached (in seconds). Add this with
2707 * time gap between system boot up to WiFi turn ON
2708 * to derive the time since boot when the
2709 * BSSID was cached.
2710 */
2711 pSirWifiScanResult->ts += pHddCtx->wifi_turn_on_time_since_boot;
2712 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2713 "Ssid (%s)"
2714 "Bssid: %pM "
2715 "Channel (%u)"
2716 "Rssi (%d)"
2717 "RTT (%u)"
2718 "RTT_SD (%u)"
2719 "Beacon Period %u"
2720 "Capability 0x%x "
2721 "Ie length %d",
2722 i,
2723 pSirWifiScanResult->ts,
2724 pSirWifiScanResult->ssid,
2725 pSirWifiScanResult->bssid,
2726 pSirWifiScanResult->channel,
2727 pSirWifiScanResult->rssi,
2728 pSirWifiScanResult->rtt,
2729 pSirWifiScanResult->rtt_sd,
2730 pSirWifiScanResult->beaconPeriod,
2731 pSirWifiScanResult->capability,
2732 ieLength);
2733
2734 ap = nla_nest_start(skb, j + 1);
2735 if (!ap)
2736 {
2737 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2738 goto fail;
2739 }
2740
2741 if (nla_put_u64(skb,
2742 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2743 pSirWifiScanResult->ts) )
2744 {
2745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2746 goto fail;
2747 }
2748 if (nla_put(skb,
2749 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2750 sizeof(pSirWifiScanResult->ssid),
2751 pSirWifiScanResult->ssid) )
2752 {
2753 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2754 goto fail;
2755 }
2756 if (nla_put(skb,
2757 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2758 sizeof(pSirWifiScanResult->bssid),
2759 pSirWifiScanResult->bssid) )
2760 {
2761 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2762 goto fail;
2763 }
2764 if (nla_put_u32(skb,
2765 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2766 pSirWifiScanResult->channel) )
2767 {
2768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2769 goto fail;
2770 }
2771 if (nla_put_s32(skb,
2772 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2773 pSirWifiScanResult->rssi) )
2774 {
2775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2776 goto fail;
2777 }
2778 if (nla_put_u32(skb,
2779 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2780 pSirWifiScanResult->rtt) )
2781 {
2782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2783 goto fail;
2784 }
2785 if (nla_put_u32(skb,
2786 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2787 pSirWifiScanResult->rtt_sd))
2788 {
2789 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2790 goto fail;
2791 }
2792 if (nla_put_u32(skb,
2793 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2794 pSirWifiScanResult->beaconPeriod))
2795 {
2796 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2797 goto fail;
2798 }
2799 if (nla_put_u32(skb,
2800 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2801 pSirWifiScanResult->capability))
2802 {
2803 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2804 goto fail;
2805 }
2806 if (nla_put_u32(skb,
2807 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2808 ieLength))
2809 {
2810 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2811 goto fail;
2812 }
2813
2814 if (ieLength)
2815 if (nla_put(skb,
2816 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2817 ieLength, ie)) {
2818 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2819 goto fail;
2820 }
2821
2822 nla_nest_end(skb, ap);
2823 }
2824 nla_nest_end(skb, aps);
2825 nla_nest_end(skb, nla_result);
2826 }
2827
2828 nla_nest_end(skb, nla_results);
2829
2830 cfg80211_vendor_cmd_reply(skb);
2831
2832 } while (totalResults > 0);
2833 }
2834
2835 if (!pData->moreData) {
2836 spin_lock(&hdd_context_lock);
2837 context->response_status = 0;
2838 complete(&context->response_event);
2839 spin_unlock(&hdd_context_lock);
2840 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302841
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302842 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302843 return;
2844fail:
2845 kfree_skb(skb);
2846 return;
2847}
2848
2849static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2850 void *pMsg)
2851{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302852 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302853 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2854 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302855 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302856
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302857 ENTER();
2858
2859 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302860 hddLog(LOGE,
2861 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302862 return;
2863 }
2864 if (!pMsg)
2865 {
2866 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302867 return;
2868 }
2869
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302870 if (pData->bss_found)
2871 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2872 else
2873 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2874
Dino Mycle6fb96c12014-06-10 11:52:40 +05302875 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302876#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2877 NULL,
2878#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302879 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302880 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302881
2882 if (!skb) {
2883 hddLog(VOS_TRACE_LEVEL_ERROR,
2884 FL("cfg80211_vendor_event_alloc failed"));
2885 return;
2886 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302887
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302888 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2889 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2890 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2891 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2892
2893 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302894 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2895 "Ssid (%s) "
2896 "Bssid (" MAC_ADDRESS_STR ") "
2897 "Channel (%u) "
2898 "Rssi (%d) "
2899 "RTT (%u) "
2900 "RTT_SD (%u) ",
2901 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302902 pData->bssHotlist[i].ts,
2903 pData->bssHotlist[i].ssid,
2904 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2905 pData->bssHotlist[i].channel,
2906 pData->bssHotlist[i].rssi,
2907 pData->bssHotlist[i].rtt,
2908 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302909 }
2910
2911 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2912 pData->requestId) ||
2913 nla_put_u32(skb,
2914 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302915 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302916 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2917 goto fail;
2918 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302919 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302920 struct nlattr *aps;
2921
2922 aps = nla_nest_start(skb,
2923 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2924 if (!aps)
2925 goto fail;
2926
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302927 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302928 struct nlattr *ap;
2929
2930 ap = nla_nest_start(skb, i + 1);
2931 if (!ap)
2932 goto fail;
2933
2934 if (nla_put_u64(skb,
2935 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302936 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302937 nla_put(skb,
2938 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302939 sizeof(pData->bssHotlist[i].ssid),
2940 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302941 nla_put(skb,
2942 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302943 sizeof(pData->bssHotlist[i].bssid),
2944 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302945 nla_put_u32(skb,
2946 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302947 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302948 nla_put_s32(skb,
2949 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302950 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302951 nla_put_u32(skb,
2952 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302953 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302954 nla_put_u32(skb,
2955 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302956 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302957 goto fail;
2958
2959 nla_nest_end(skb, ap);
2960 }
2961 nla_nest_end(skb, aps);
2962
2963 if (nla_put_u8(skb,
2964 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2965 pData->moreData))
2966 goto fail;
2967 }
2968
2969 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302970 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302971 return;
2972
2973fail:
2974 kfree_skb(skb);
2975 return;
2976
2977}
Dino Mycle6fb96c12014-06-10 11:52:40 +05302978
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302979/**
2980 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
2981 * Handle an SSID hotlist match event
2982 * @ctx: HDD context registered with SME
2983 * @event: The SSID hotlist match event
2984 *
2985 * This function will take an SSID match event that was generated by
2986 * firmware and will convert it into a cfg80211 vendor event which is
2987 * sent to userspace.
2988 *
2989 * Return: none
2990 */
2991static void
2992wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
2993 void *pMsg)
2994{
2995 hdd_context_t *hdd_ctx = ctx;
2996 struct sk_buff *skb;
2997 tANI_U32 i, index;
2998 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
2999
3000 ENTER();
3001
3002 if (wlan_hdd_validate_context(hdd_ctx)) {
3003 hddLog(LOGE,
3004 FL("HDD context is not valid or response"));
3005 return;
3006 }
3007 if (!pMsg)
3008 {
3009 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3010 return;
3011 }
3012
3013 if (pData->ssid_found) {
3014 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3015 hddLog(LOG1, "SSID hotlist found");
3016 } else {
3017 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3018 hddLog(LOG1, "SSID hotlist lost");
3019 }
3020
3021 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3022#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3023 NULL,
3024#endif
3025 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3026 index, GFP_KERNEL);
3027
3028 if (!skb) {
3029 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3030 return;
3031 }
3032 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3033 pData->requestId, pData->numHotlistSsid, pData->moreData);
3034
3035 for (i = 0; i < pData->numHotlistSsid; i++) {
3036 hddLog(LOG1, "[i=%d] Timestamp %llu "
3037 "Ssid: %s "
3038 "Bssid (" MAC_ADDRESS_STR ") "
3039 "Channel %u "
3040 "Rssi %d "
3041 "RTT %u "
3042 "RTT_SD %u",
3043 i,
3044 pData->ssidHotlist[i].ts,
3045 pData->ssidHotlist[i].ssid,
3046 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3047 pData->ssidHotlist[i].channel,
3048 pData->ssidHotlist[i].rssi,
3049 pData->ssidHotlist[i].rtt,
3050 pData->ssidHotlist[i].rtt_sd);
3051 }
3052
3053 if (nla_put_u32(skb,
3054 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3055 pData->requestId) ||
3056 nla_put_u32(skb,
3057 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3058 pData->numHotlistSsid)) {
3059 hddLog(LOGE, FL("put fail"));
3060 goto fail;
3061 }
3062
3063 if (pData->numHotlistSsid) {
3064 struct nlattr *aps;
3065 aps = nla_nest_start(skb,
3066 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3067 if (!aps) {
3068 hddLog(LOGE, FL("nest fail"));
3069 goto fail;
3070 }
3071
3072 for (i = 0; i < pData->numHotlistSsid; i++) {
3073 struct nlattr *ap;
3074
3075 ap = nla_nest_start(skb, i);
3076 if (!ap) {
3077 hddLog(LOGE, FL("nest fail"));
3078 goto fail;
3079 }
3080
3081 if (nla_put_u64(skb,
3082 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3083 pData->ssidHotlist[i].ts) ||
3084 nla_put(skb,
3085 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3086 sizeof(pData->ssidHotlist[i].ssid),
3087 pData->ssidHotlist[i].ssid) ||
3088 nla_put(skb,
3089 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3090 sizeof(pData->ssidHotlist[i].bssid),
3091 pData->ssidHotlist[i].bssid) ||
3092 nla_put_u32(skb,
3093 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3094 pData->ssidHotlist[i].channel) ||
3095 nla_put_s32(skb,
3096 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3097 pData->ssidHotlist[i].rssi) ||
3098 nla_put_u32(skb,
3099 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3100 pData->ssidHotlist[i].rtt) ||
3101 nla_put_u32(skb,
3102 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3103 pData->ssidHotlist[i].rtt_sd)) {
3104 hddLog(LOGE, FL("put fail"));
3105 goto fail;
3106 }
3107 nla_nest_end(skb, ap);
3108 }
3109 nla_nest_end(skb, aps);
3110
3111 if (nla_put_u8(skb,
3112 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3113 pData->moreData)) {
3114 hddLog(LOGE, FL("put fail"));
3115 goto fail;
3116 }
3117 }
3118
3119 cfg80211_vendor_event(skb, GFP_KERNEL);
3120 return;
3121
3122fail:
3123 kfree_skb(skb);
3124 return;
3125
3126}
3127
3128
Dino Mycle6fb96c12014-06-10 11:52:40 +05303129static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3130 void *pMsg)
3131{
3132 struct sk_buff *skb;
3133 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3134 tpSirWifiFullScanResultEvent pData =
3135 (tpSirWifiFullScanResultEvent) (pMsg);
3136
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303137 ENTER();
3138
3139 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303140 hddLog(LOGE,
3141 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303142 return;
3143 }
3144 if (!pMsg)
3145 {
3146 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303147 return;
3148 }
3149
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303150 /*
3151 * If the full scan result including IE data exceeds NL 4K size
3152 * limitation, drop that beacon/probe rsp frame.
3153 */
3154 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3155 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3156 return;
3157 }
3158
Dino Mycle6fb96c12014-06-10 11:52:40 +05303159 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303160#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3161 NULL,
3162#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303163 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3164 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3165 GFP_KERNEL);
3166
3167 if (!skb) {
3168 hddLog(VOS_TRACE_LEVEL_ERROR,
3169 FL("cfg80211_vendor_event_alloc failed"));
3170 return;
3171 }
3172
Dino Mycle6fb96c12014-06-10 11:52:40 +05303173 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3174 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3175 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3176 "Ssid (%s)"
3177 "Bssid (" MAC_ADDRESS_STR ")"
3178 "Channel (%u)"
3179 "Rssi (%d)"
3180 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303181 "RTT_SD (%u)"
3182 "Bcn Period %d"
3183 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303184 pData->ap.ts,
3185 pData->ap.ssid,
3186 MAC_ADDR_ARRAY(pData->ap.bssid),
3187 pData->ap.channel,
3188 pData->ap.rssi,
3189 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303190 pData->ap.rtt_sd,
3191 pData->ap.beaconPeriod,
3192 pData->ap.capability);
3193
Dino Mycle6fb96c12014-06-10 11:52:40 +05303194 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3195 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3196 pData->requestId) ||
3197 nla_put_u64(skb,
3198 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3199 pData->ap.ts) ||
3200 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3201 sizeof(pData->ap.ssid),
3202 pData->ap.ssid) ||
3203 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3204 WNI_CFG_BSSID_LEN,
3205 pData->ap.bssid) ||
3206 nla_put_u32(skb,
3207 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3208 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303209 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303210 pData->ap.rssi) ||
3211 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3212 pData->ap.rtt) ||
3213 nla_put_u32(skb,
3214 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3215 pData->ap.rtt_sd) ||
3216 nla_put_u16(skb,
3217 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3218 pData->ap.beaconPeriod) ||
3219 nla_put_u16(skb,
3220 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3221 pData->ap.capability) ||
3222 nla_put_u32(skb,
3223 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303224 pData->ieLength) ||
3225 nla_put_u8(skb,
3226 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3227 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303228 {
3229 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3230 goto nla_put_failure;
3231 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303232
3233 if (pData->ieLength) {
3234 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3235 pData->ieLength,
3236 pData->ie))
3237 {
3238 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3239 goto nla_put_failure;
3240 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303241 }
3242
3243 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303244 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303245 return;
3246
3247nla_put_failure:
3248 kfree_skb(skb);
3249 return;
3250}
3251
3252static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3253 void *pMsg)
3254{
3255 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3256 struct sk_buff *skb = NULL;
3257 tpSirEXTScanResultsAvailableIndParams pData =
3258 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3259
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303260 ENTER();
3261
3262 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303263 hddLog(LOGE,
3264 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303265 return;
3266 }
3267 if (!pMsg)
3268 {
3269 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303270 return;
3271 }
3272
3273 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303274#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3275 NULL,
3276#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303277 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3278 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3279 GFP_KERNEL);
3280
3281 if (!skb) {
3282 hddLog(VOS_TRACE_LEVEL_ERROR,
3283 FL("cfg80211_vendor_event_alloc failed"));
3284 return;
3285 }
3286
Dino Mycle6fb96c12014-06-10 11:52:40 +05303287 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3288 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3289 pData->numResultsAvailable);
3290 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3291 pData->requestId) ||
3292 nla_put_u32(skb,
3293 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3294 pData->numResultsAvailable)) {
3295 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3296 goto nla_put_failure;
3297 }
3298
3299 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303300 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303301 return;
3302
3303nla_put_failure:
3304 kfree_skb(skb);
3305 return;
3306}
3307
3308static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3309{
3310 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3311 struct sk_buff *skb = NULL;
3312 tpSirEXTScanProgressIndParams pData =
3313 (tpSirEXTScanProgressIndParams) pMsg;
3314
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303315 ENTER();
3316
3317 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303318 hddLog(LOGE,
3319 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303320 return;
3321 }
3322 if (!pMsg)
3323 {
3324 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303325 return;
3326 }
3327
3328 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303329#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3330 NULL,
3331#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303332 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3333 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3334 GFP_KERNEL);
3335
3336 if (!skb) {
3337 hddLog(VOS_TRACE_LEVEL_ERROR,
3338 FL("cfg80211_vendor_event_alloc failed"));
3339 return;
3340 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303341 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303342 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3343 pData->extScanEventType);
3344 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3345 pData->status);
3346
3347 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3348 pData->extScanEventType) ||
3349 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303350 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3351 pData->requestId) ||
3352 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303353 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3354 pData->status)) {
3355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3356 goto nla_put_failure;
3357 }
3358
3359 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303360 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303361 return;
3362
3363nla_put_failure:
3364 kfree_skb(skb);
3365 return;
3366}
3367
3368void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3369 void *pMsg)
3370{
3371 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3372
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303373 ENTER();
3374
Dino Mycle6fb96c12014-06-10 11:52:40 +05303375 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303376 return;
3377 }
3378
3379 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3380
3381
3382 switch(evType) {
3383 case SIR_HAL_EXTSCAN_START_RSP:
3384 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3385 break;
3386
3387 case SIR_HAL_EXTSCAN_STOP_RSP:
3388 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3389 break;
3390 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3391 /* There is no need to send this response to upper layer
3392 Just log the message */
3393 hddLog(VOS_TRACE_LEVEL_INFO,
3394 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3395 break;
3396 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3397 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3398 break;
3399
3400 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3401 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3402 break;
3403
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303404 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3405 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3406 break;
3407
3408 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3409 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3410 break;
3411
Dino Mycle6fb96c12014-06-10 11:52:40 +05303412 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303413 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303414 break;
3415 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3416 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3417 break;
3418 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3419 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3420 break;
3421 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3422 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3423 break;
3424 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3425 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3426 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303427 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3428 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3429 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303430 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3431 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3432 break;
3433 default:
3434 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3435 break;
3436 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303437 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303438}
3439
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303440static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3441 struct wireless_dev *wdev,
3442 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303443{
Dino Myclee8843b32014-07-04 14:21:45 +05303444 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303445 struct net_device *dev = wdev->netdev;
3446 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3447 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3448 struct nlattr
3449 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3450 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303451 struct hdd_ext_scan_context *context;
3452 unsigned long rc;
3453 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303454
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303455 ENTER();
3456
Dino Mycle6fb96c12014-06-10 11:52:40 +05303457 status = wlan_hdd_validate_context(pHddCtx);
3458 if (0 != status)
3459 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460 return -EINVAL;
3461 }
Dino Myclee8843b32014-07-04 14:21:45 +05303462 /* check the EXTScan Capability */
3463 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3464 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3465 {
3466 hddLog(VOS_TRACE_LEVEL_ERROR,
3467 FL("EXTScan not enabled/supported by Firmware"));
3468 return -EINVAL;
3469 }
3470
Dino Mycle6fb96c12014-06-10 11:52:40 +05303471 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3472 data, dataLen,
3473 wlan_hdd_extscan_config_policy)) {
3474 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3475 return -EINVAL;
3476 }
3477
3478 /* Parse and fetch request Id */
3479 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3480 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3481 return -EINVAL;
3482 }
3483
Dino Myclee8843b32014-07-04 14:21:45 +05303484 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303485 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303486 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303487
Dino Myclee8843b32014-07-04 14:21:45 +05303488 reqMsg.sessionId = pAdapter->sessionId;
3489 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303490
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303491 vos_spin_lock_acquire(&hdd_context_lock);
3492 context = &pHddCtx->ext_scan_context;
3493 context->request_id = reqMsg.requestId;
3494 INIT_COMPLETION(context->response_event);
3495 vos_spin_lock_release(&hdd_context_lock);
3496
Dino Myclee8843b32014-07-04 14:21:45 +05303497 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303498 if (!HAL_STATUS_SUCCESS(status)) {
3499 hddLog(VOS_TRACE_LEVEL_ERROR,
3500 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303501 return -EINVAL;
3502 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303503
3504 rc = wait_for_completion_timeout(&context->response_event,
3505 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3506 if (!rc) {
3507 hddLog(LOGE, FL("Target response timed out"));
3508 return -ETIMEDOUT;
3509 }
3510
3511 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3512 if (ret)
3513 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3514
3515 return ret;
3516
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303517 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303518 return 0;
3519}
3520
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303521static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3522 struct wireless_dev *wdev,
3523 const void *data, int dataLen)
3524{
3525 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303526
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303527 vos_ssr_protect(__func__);
3528 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3529 vos_ssr_unprotect(__func__);
3530
3531 return ret;
3532}
3533
3534static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3535 struct wireless_dev *wdev,
3536 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303537{
Dino Myclee8843b32014-07-04 14:21:45 +05303538 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303539 struct net_device *dev = wdev->netdev;
3540 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3541 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3542 struct nlattr
3543 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3544 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303545 struct hdd_ext_scan_context *context;
3546 unsigned long rc;
3547 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303548
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303549 ENTER();
3550
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303551 if (VOS_FTM_MODE == hdd_get_conparam()) {
3552 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3553 return -EINVAL;
3554 }
3555
Dino Mycle6fb96c12014-06-10 11:52:40 +05303556 status = wlan_hdd_validate_context(pHddCtx);
3557 if (0 != status)
3558 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303559 return -EINVAL;
3560 }
Dino Myclee8843b32014-07-04 14:21:45 +05303561 /* check the EXTScan Capability */
3562 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3563 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3564 {
3565 hddLog(VOS_TRACE_LEVEL_ERROR,
3566 FL("EXTScan not enabled/supported by Firmware"));
3567 return -EINVAL;
3568 }
3569
Dino Mycle6fb96c12014-06-10 11:52:40 +05303570 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3571 data, dataLen,
3572 wlan_hdd_extscan_config_policy)) {
3573 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3574 return -EINVAL;
3575 }
3576 /* Parse and fetch request Id */
3577 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3578 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3579 return -EINVAL;
3580 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303581
Dino Myclee8843b32014-07-04 14:21:45 +05303582 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303583 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3584
Dino Myclee8843b32014-07-04 14:21:45 +05303585 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303586
Dino Myclee8843b32014-07-04 14:21:45 +05303587 reqMsg.sessionId = pAdapter->sessionId;
3588 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303589
3590 /* Parse and fetch flush parameter */
3591 if (!tb
3592 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3593 {
3594 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3595 goto failed;
3596 }
Dino Myclee8843b32014-07-04 14:21:45 +05303597 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303598 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3599
Dino Myclee8843b32014-07-04 14:21:45 +05303600 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303601
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303602 spin_lock(&hdd_context_lock);
3603 context = &pHddCtx->ext_scan_context;
3604 context->request_id = reqMsg.requestId;
3605 context->ignore_cached_results = false;
3606 INIT_COMPLETION(context->response_event);
3607 spin_unlock(&hdd_context_lock);
3608
Dino Myclee8843b32014-07-04 14:21:45 +05303609 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303610 if (!HAL_STATUS_SUCCESS(status)) {
3611 hddLog(VOS_TRACE_LEVEL_ERROR,
3612 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303613 return -EINVAL;
3614 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303615
3616 rc = wait_for_completion_timeout(&context->response_event,
3617 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3618 if (!rc) {
3619 hddLog(LOGE, FL("Target response timed out"));
3620 retval = -ETIMEDOUT;
3621 spin_lock(&hdd_context_lock);
3622 context->ignore_cached_results = true;
3623 spin_unlock(&hdd_context_lock);
3624 } else {
3625 spin_lock(&hdd_context_lock);
3626 retval = context->response_status;
3627 spin_unlock(&hdd_context_lock);
3628 }
3629
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303630 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303631 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303632
3633failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303634 return -EINVAL;
3635}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303636static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3637 struct wireless_dev *wdev,
3638 const void *data, int dataLen)
3639{
3640 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303641
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303642 vos_ssr_protect(__func__);
3643 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3644 vos_ssr_unprotect(__func__);
3645
3646 return ret;
3647}
3648
3649static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303650 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303651 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303652{
3653 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3654 struct net_device *dev = wdev->netdev;
3655 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3656 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3657 struct nlattr
3658 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3659 struct nlattr
3660 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3661 struct nlattr *apTh;
3662 eHalStatus status;
3663 tANI_U8 i = 0;
3664 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303665 struct hdd_ext_scan_context *context;
3666 tANI_U32 request_id;
3667 unsigned long rc;
3668 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303669
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303670 ENTER();
3671
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303672 if (VOS_FTM_MODE == hdd_get_conparam()) {
3673 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3674 return -EINVAL;
3675 }
3676
Dino Mycle6fb96c12014-06-10 11:52:40 +05303677 status = wlan_hdd_validate_context(pHddCtx);
3678 if (0 != status)
3679 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303680 return -EINVAL;
3681 }
Dino Myclee8843b32014-07-04 14:21:45 +05303682 /* check the EXTScan Capability */
3683 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3684 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3685 {
3686 hddLog(VOS_TRACE_LEVEL_ERROR,
3687 FL("EXTScan not enabled/supported by Firmware"));
3688 return -EINVAL;
3689 }
3690
Dino Mycle6fb96c12014-06-10 11:52:40 +05303691 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3692 data, dataLen,
3693 wlan_hdd_extscan_config_policy)) {
3694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3695 return -EINVAL;
3696 }
3697
3698 /* Parse and fetch request Id */
3699 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3700 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3701 return -EINVAL;
3702 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303703 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3704 vos_mem_malloc(sizeof(*pReqMsg));
3705 if (!pReqMsg) {
3706 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3707 return -ENOMEM;
3708 }
3709
Dino Myclee8843b32014-07-04 14:21:45 +05303710
Dino Mycle6fb96c12014-06-10 11:52:40 +05303711 pReqMsg->requestId = nla_get_u32(
3712 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3713 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3714
3715 /* Parse and fetch number of APs */
3716 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3717 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3718 goto fail;
3719 }
3720
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303721 /* Parse and fetch lost ap sample size */
3722 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3723 hddLog(LOGE, FL("attr lost ap sample size failed"));
3724 goto fail;
3725 }
3726
3727 pReqMsg->lostBssidSampleSize = nla_get_u32(
3728 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3729 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3730
Dino Mycle6fb96c12014-06-10 11:52:40 +05303731 pReqMsg->sessionId = pAdapter->sessionId;
3732 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3733
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303734 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303735 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303736 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303737
3738 nla_for_each_nested(apTh,
3739 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3740 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3741 nla_data(apTh), nla_len(apTh),
3742 NULL)) {
3743 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3744 goto fail;
3745 }
3746
3747 /* Parse and fetch MAC address */
3748 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3749 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3750 goto fail;
3751 }
3752 memcpy(pReqMsg->ap[i].bssid, nla_data(
3753 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3754 sizeof(tSirMacAddr));
3755 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3756
3757 /* Parse and fetch low RSSI */
3758 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3759 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3760 goto fail;
3761 }
3762 pReqMsg->ap[i].low = nla_get_s32(
3763 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3764 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3765
3766 /* Parse and fetch high RSSI */
3767 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3769 goto fail;
3770 }
3771 pReqMsg->ap[i].high = nla_get_s32(
3772 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3773 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3774 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303775 i++;
3776 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303777
3778 context = &pHddCtx->ext_scan_context;
3779 spin_lock(&hdd_context_lock);
3780 INIT_COMPLETION(context->response_event);
3781 context->request_id = request_id = pReqMsg->requestId;
3782 spin_unlock(&hdd_context_lock);
3783
Dino Mycle6fb96c12014-06-10 11:52:40 +05303784 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3785 if (!HAL_STATUS_SUCCESS(status)) {
3786 hddLog(VOS_TRACE_LEVEL_ERROR,
3787 FL("sme_SetBssHotlist failed(err=%d)"), status);
3788 vos_mem_free(pReqMsg);
3789 return -EINVAL;
3790 }
3791
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303792 /* request was sent -- wait for the response */
3793 rc = wait_for_completion_timeout(&context->response_event,
3794 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3795
3796 if (!rc) {
3797 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3798 retval = -ETIMEDOUT;
3799 } else {
3800 spin_lock(&hdd_context_lock);
3801 if (context->request_id == request_id)
3802 retval = context->response_status;
3803 else
3804 retval = -EINVAL;
3805 spin_unlock(&hdd_context_lock);
3806 }
3807
Dino Myclee8843b32014-07-04 14:21:45 +05303808 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303809 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303810 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303811
3812fail:
3813 vos_mem_free(pReqMsg);
3814 return -EINVAL;
3815}
3816
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303817static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3818 struct wireless_dev *wdev,
3819 const void *data, int dataLen)
3820{
3821 int ret = 0;
3822
3823 vos_ssr_protect(__func__);
3824 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3825 dataLen);
3826 vos_ssr_unprotect(__func__);
3827
3828 return ret;
3829}
3830
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303831/*
3832 * define short names for the global vendor params
3833 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3834 */
3835#define PARAM_MAX \
3836QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3837#define PARAM_REQUEST_ID \
3838QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3839#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3840QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3841#define PARAMS_NUM_SSID \
3842QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3843#define THRESHOLD_PARAM \
3844QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3845#define PARAM_SSID \
3846QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3847#define PARAM_BAND \
3848QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3849#define PARAM_RSSI_LOW \
3850QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3851#define PARAM_RSSI_HIGH \
3852QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3853
3854/**
3855 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3856 * @wiphy: Pointer to wireless phy
3857 * @wdev: Pointer to wireless device
3858 * @data: Pointer to data
3859 * @data_len: Data length
3860 *
3861 * Return: 0 on success, negative errno on failure
3862 */
3863static int
3864__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3865 struct wireless_dev *wdev,
3866 const void *data,
3867 int data_len)
3868{
3869 tSirEXTScanSetSsidHotListReqParams *request;
3870 struct net_device *dev = wdev->netdev;
3871 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3872 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3873 struct nlattr *tb[PARAM_MAX + 1];
3874 struct nlattr *tb2[PARAM_MAX + 1];
3875 struct nlattr *ssids;
3876 struct hdd_ext_scan_context *context;
3877 uint32_t request_id;
3878 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3879 int ssid_len;
3880 eHalStatus status;
3881 int i, rem, retval;
3882 unsigned long rc;
3883
3884 ENTER();
3885
3886 if (VOS_FTM_MODE == hdd_get_conparam()) {
3887 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3888 return -EINVAL;
3889 }
3890
3891 retval = wlan_hdd_validate_context(hdd_ctx);
3892 if (0 != retval) {
3893 hddLog(LOGE, FL("HDD context is not valid"));
3894 return -EINVAL;
3895 }
3896
3897 /* check the EXTScan Capability */
3898 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
3899 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3900 {
3901 hddLog(VOS_TRACE_LEVEL_ERROR,
3902 FL("EXTScan not enabled/supported by Firmware"));
3903 return -EINVAL;
3904 }
3905
3906 if (nla_parse(tb, PARAM_MAX,
3907 data, data_len,
3908 wlan_hdd_extscan_config_policy)) {
3909 hddLog(LOGE, FL("Invalid ATTR"));
3910 return -EINVAL;
3911 }
3912
3913 request = vos_mem_malloc(sizeof(*request));
3914 if (!request) {
3915 hddLog(LOGE, FL("vos_mem_malloc failed"));
3916 return -ENOMEM;
3917 }
3918
3919 /* Parse and fetch request Id */
3920 if (!tb[PARAM_REQUEST_ID]) {
3921 hddLog(LOGE, FL("attr request id failed"));
3922 goto fail;
3923 }
3924
3925 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3926 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3927
3928 /* Parse and fetch lost SSID sample size */
3929 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3930 hddLog(LOGE, FL("attr number of Ssid failed"));
3931 goto fail;
3932 }
3933 request->lost_ssid_sample_size =
3934 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3935 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3936 request->lost_ssid_sample_size);
3937
3938 /* Parse and fetch number of hotlist SSID */
3939 if (!tb[PARAMS_NUM_SSID]) {
3940 hddLog(LOGE, FL("attr number of Ssid failed"));
3941 goto fail;
3942 }
3943 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3944 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3945
3946 request->session_id = adapter->sessionId;
3947 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3948
3949 i = 0;
3950 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3951 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3952 hddLog(LOGE,
3953 FL("Too Many SSIDs, %d exceeds %d"),
3954 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3955 break;
3956 }
3957 if (nla_parse(tb2, PARAM_MAX,
3958 nla_data(ssids), nla_len(ssids),
3959 wlan_hdd_extscan_config_policy)) {
3960 hddLog(LOGE, FL("nla_parse failed"));
3961 goto fail;
3962 }
3963
3964 /* Parse and fetch SSID */
3965 if (!tb2[PARAM_SSID]) {
3966 hddLog(LOGE, FL("attr ssid failed"));
3967 goto fail;
3968 }
3969 nla_memcpy(ssid_string,
3970 tb2[PARAM_SSID],
3971 sizeof(ssid_string));
3972 hddLog(LOG1, FL("SSID %s"),
3973 ssid_string);
3974 ssid_len = strlen(ssid_string);
3975 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
3976 request->ssid[i].ssid.length = ssid_len;
3977 request->ssid[i].ssid.ssId[ssid_len] = '\0';
3978 hddLog(LOG1, FL("After copying SSID %s"),
3979 request->ssid[i].ssid.ssId);
3980 hddLog(LOG1, FL("After copying length: %d"),
3981 ssid_len);
3982
3983 /* Parse and fetch low RSSI */
3984 if (!tb2[PARAM_BAND]) {
3985 hddLog(LOGE, FL("attr band failed"));
3986 goto fail;
3987 }
3988 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
3989 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
3990
3991 /* Parse and fetch low RSSI */
3992 if (!tb2[PARAM_RSSI_LOW]) {
3993 hddLog(LOGE, FL("attr low RSSI failed"));
3994 goto fail;
3995 }
3996 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
3997 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
3998
3999 /* Parse and fetch high RSSI */
4000 if (!tb2[PARAM_RSSI_HIGH]) {
4001 hddLog(LOGE, FL("attr high RSSI failed"));
4002 goto fail;
4003 }
4004 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4005 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4006 i++;
4007 }
4008
4009 context = &hdd_ctx->ext_scan_context;
4010 spin_lock(&hdd_context_lock);
4011 INIT_COMPLETION(context->response_event);
4012 context->request_id = request_id = request->request_id;
4013 spin_unlock(&hdd_context_lock);
4014
4015 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4016 if (!HAL_STATUS_SUCCESS(status)) {
4017 hddLog(LOGE,
4018 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4019 goto fail;
4020 }
4021
4022 vos_mem_free(request);
4023
4024 /* request was sent -- wait for the response */
4025 rc = wait_for_completion_timeout(&context->response_event,
4026 msecs_to_jiffies
4027 (WLAN_WAIT_TIME_EXTSCAN));
4028 if (!rc) {
4029 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4030 retval = -ETIMEDOUT;
4031 } else {
4032 spin_lock(&hdd_context_lock);
4033 if (context->request_id == request_id)
4034 retval = context->response_status;
4035 else
4036 retval = -EINVAL;
4037 spin_unlock(&hdd_context_lock);
4038 }
4039
4040 return retval;
4041
4042fail:
4043 vos_mem_free(request);
4044 return -EINVAL;
4045}
4046
4047/*
4048 * done with short names for the global vendor params
4049 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4050 */
4051#undef PARAM_MAX
4052#undef PARAM_REQUEST_ID
4053#undef PARAMS_NUM_SSID
4054#undef THRESHOLD_PARAM
4055#undef PARAM_SSID
4056#undef PARAM_BAND
4057#undef PARAM_RSSI_LOW
4058#undef PARAM_RSSI_HIGH
4059
4060static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4061 struct wireless_dev *wdev,
4062 const void *data, int dataLen)
4063{
4064 int ret = 0;
4065
4066 vos_ssr_protect(__func__);
4067 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4068 dataLen);
4069 vos_ssr_unprotect(__func__);
4070
4071 return ret;
4072}
4073
4074static int
4075__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4076 struct wireless_dev *wdev,
4077 const void *data,
4078 int data_len)
4079{
4080 tSirEXTScanResetSsidHotlistReqParams request;
4081 struct net_device *dev = wdev->netdev;
4082 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4083 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4084 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4085 struct hdd_ext_scan_context *context;
4086 uint32_t request_id;
4087 eHalStatus status;
4088 int retval;
4089 unsigned long rc;
4090
4091 ENTER();
4092
4093 if (VOS_FTM_MODE == hdd_get_conparam()) {
4094 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4095 return -EINVAL;
4096 }
4097
4098 retval = wlan_hdd_validate_context(hdd_ctx);
4099 if (0 != retval) {
4100 hddLog(LOGE, FL("HDD context is not valid"));
4101 return -EINVAL;
4102 }
4103
4104 /* check the EXTScan Capability */
4105 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
4106 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4107 {
4108 hddLog(LOGE,
4109 FL("EXTScan not enabled/supported by Firmware"));
4110 return -EINVAL;
4111 }
4112
4113 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4114 data, data_len,
4115 wlan_hdd_extscan_config_policy)) {
4116 hddLog(LOGE, FL("Invalid ATTR"));
4117 return -EINVAL;
4118 }
4119
4120 /* Parse and fetch request Id */
4121 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4122 hddLog(LOGE, FL("attr request id failed"));
4123 return -EINVAL;
4124 }
4125
4126 request.requestId = nla_get_u32(
4127 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4128 request.sessionId = adapter->sessionId;
4129 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4130 request.sessionId);
4131
4132 context = &hdd_ctx->ext_scan_context;
4133 spin_lock(&hdd_context_lock);
4134 INIT_COMPLETION(context->response_event);
4135 context->request_id = request_id = request.requestId;
4136 spin_unlock(&hdd_context_lock);
4137
4138 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4139 if (!HAL_STATUS_SUCCESS(status)) {
4140 hddLog(LOGE,
4141 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4142 return -EINVAL;
4143 }
4144
4145 /* request was sent -- wait for the response */
4146 rc = wait_for_completion_timeout(&context->response_event,
4147 msecs_to_jiffies
4148 (WLAN_WAIT_TIME_EXTSCAN));
4149 if (!rc) {
4150 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4151 retval = -ETIMEDOUT;
4152 } else {
4153 spin_lock(&hdd_context_lock);
4154 if (context->request_id == request_id)
4155 retval = context->response_status;
4156 else
4157 retval = -EINVAL;
4158 spin_unlock(&hdd_context_lock);
4159 }
4160
4161 return retval;
4162}
4163
4164static int
4165wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4166 struct wireless_dev *wdev,
4167 const void *data,
4168 int data_len)
4169{
4170 int ret;
4171
4172 vos_ssr_protect(__func__);
4173 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4174 data, data_len);
4175 vos_ssr_unprotect(__func__);
4176
4177 return ret;
4178}
4179
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304180static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304181 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304182 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304183{
4184 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4185 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4186 tANI_U8 numChannels = 0;
4187 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304188 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304189 tWifiBand wifiBand;
4190 eHalStatus status;
4191 struct sk_buff *replySkb;
4192 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304193 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304194
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304195 ENTER();
4196
Dino Mycle6fb96c12014-06-10 11:52:40 +05304197 status = wlan_hdd_validate_context(pHddCtx);
4198 if (0 != status)
4199 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304200 return -EINVAL;
4201 }
Dino Myclee8843b32014-07-04 14:21:45 +05304202
Dino Mycle6fb96c12014-06-10 11:52:40 +05304203 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4204 data, dataLen,
4205 wlan_hdd_extscan_config_policy)) {
4206 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4207 return -EINVAL;
4208 }
4209
4210 /* Parse and fetch request Id */
4211 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4212 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4213 return -EINVAL;
4214 }
4215 requestId = nla_get_u32(
4216 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4217 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4218
4219 /* Parse and fetch wifi band */
4220 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4221 {
4222 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4223 return -EINVAL;
4224 }
4225 wifiBand = nla_get_u32(
4226 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4227 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4228
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304229 /* Parse and fetch max channels */
4230 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4231 {
4232 hddLog(LOGE, FL("attr max channels failed"));
4233 return -EINVAL;
4234 }
4235 maxChannels = nla_get_u32(
4236 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4237 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4238
Dino Mycle6fb96c12014-06-10 11:52:40 +05304239 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
4240 wifiBand, ChannelList,
4241 &numChannels);
4242 if (eHAL_STATUS_SUCCESS != status) {
4243 hddLog(VOS_TRACE_LEVEL_ERROR,
4244 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4245 return -EINVAL;
4246 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304247
4248 numChannels = VOS_MIN(numChannels, maxChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304249 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304250
Dino Mycle6fb96c12014-06-10 11:52:40 +05304251 for (i = 0; i < numChannels; i++)
4252 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
4253
4254 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4255 sizeof(u32) * numChannels +
4256 NLMSG_HDRLEN);
4257
4258 if (!replySkb) {
4259 hddLog(VOS_TRACE_LEVEL_ERROR,
4260 FL("valid channels: buffer alloc fail"));
4261 return -EINVAL;
4262 }
4263 if (nla_put_u32(replySkb,
4264 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
4265 numChannels) ||
4266 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
4267 sizeof(u32) * numChannels, ChannelList)) {
4268
4269 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4270 kfree_skb(replySkb);
4271 return -EINVAL;
4272 }
4273
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304274 ret = cfg80211_vendor_cmd_reply(replySkb);
4275
4276 EXIT();
4277 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304278}
4279
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304280static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4281 struct wireless_dev *wdev,
4282 const void *data, int dataLen)
4283{
4284 int ret = 0;
4285
4286 vos_ssr_protect(__func__);
4287 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4288 dataLen);
4289 vos_ssr_unprotect(__func__);
4290
4291 return ret;
4292}
4293
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304294static int hdd_extscan_start_fill_bucket_channel_spec(
4295 hdd_context_t *pHddCtx,
4296 tpSirEXTScanStartReqParams pReqMsg,
4297 struct nlattr **tb)
4298{
4299 struct nlattr *bucket[
4300 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4301 struct nlattr *channel[
4302 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4303 struct nlattr *buckets;
4304 struct nlattr *channels;
4305 int rem1, rem2;
4306 eHalStatus status;
4307 tANI_U8 bktIndex, j, numChannels;
4308 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4309 tANI_U32 passive_max_chn_time, active_max_chn_time;
4310
4311 bktIndex = 0;
4312
4313 nla_for_each_nested(buckets,
4314 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4315 if (nla_parse(bucket,
4316 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4317 nla_data(buckets), nla_len(buckets), NULL)) {
4318 hddLog(LOGE, FL("nla_parse failed"));
4319 return -EINVAL;
4320 }
4321
4322 /* Parse and fetch bucket spec */
4323 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4324 hddLog(LOGE, FL("attr bucket index failed"));
4325 return -EINVAL;
4326 }
4327 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4328 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4329 hddLog(LOG1, FL("Bucket spec Index %d"),
4330 pReqMsg->buckets[bktIndex].bucket);
4331
4332 /* Parse and fetch wifi band */
4333 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4334 hddLog(LOGE, FL("attr wifi band failed"));
4335 return -EINVAL;
4336 }
4337 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4338 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4339 hddLog(LOG1, FL("Wifi band %d"),
4340 pReqMsg->buckets[bktIndex].band);
4341
4342 /* Parse and fetch period */
4343 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4344 hddLog(LOGE, FL("attr period failed"));
4345 return -EINVAL;
4346 }
4347 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4348 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4349 hddLog(LOG1, FL("period %d"),
4350 pReqMsg->buckets[bktIndex].period);
4351
4352 /* Parse and fetch report events */
4353 if (!bucket[
4354 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4355 hddLog(LOGE, FL("attr report events failed"));
4356 return -EINVAL;
4357 }
4358 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4359 bucket[
4360 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4361 hddLog(LOG1, FL("report events %d"),
4362 pReqMsg->buckets[bktIndex].reportEvents);
4363
4364 /* Parse and fetch max period */
4365 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4366 hddLog(LOGE, FL("attr max period failed"));
4367 return -EINVAL;
4368 }
4369 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4370 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4371 hddLog(LOG1, FL("max period %u"),
4372 pReqMsg->buckets[bktIndex].max_period);
4373
4374 /* Parse and fetch exponent */
4375 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4376 hddLog(LOGE, FL("attr exponent failed"));
4377 return -EINVAL;
4378 }
4379 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4380 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4381 hddLog(LOG1, FL("exponent %u"),
4382 pReqMsg->buckets[bktIndex].exponent);
4383
4384 /* Parse and fetch step count */
4385 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4386 hddLog(LOGE, FL("attr step count failed"));
4387 return -EINVAL;
4388 }
4389 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4390 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4391 hddLog(LOG1, FL("Step count %u"),
4392 pReqMsg->buckets[bktIndex].step_count);
4393
4394 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4395 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4396
4397 /* Framework shall pass the channel list if the input WiFi band is
4398 * WIFI_BAND_UNSPECIFIED.
4399 * If the input WiFi band is specified (any value other than
4400 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4401 */
4402 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4403 numChannels = 0;
4404 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4405 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4406 pReqMsg->buckets[bktIndex].band,
4407 chanList, &numChannels);
4408 if (!HAL_STATUS_SUCCESS(status)) {
4409 hddLog(LOGE,
4410 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4411 status);
4412 return -EINVAL;
4413 }
4414
4415 pReqMsg->buckets[bktIndex].numChannels =
4416 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4417 hddLog(LOG1, FL("Num channels %d"),
4418 pReqMsg->buckets[bktIndex].numChannels);
4419
4420 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4421 j++) {
4422 pReqMsg->buckets[bktIndex].channels[j].channel =
4423 chanList[j];
4424 pReqMsg->buckets[bktIndex].channels[j].
4425 chnlClass = 0;
4426 if (CSR_IS_CHANNEL_DFS(
4427 vos_freq_to_chan(chanList[j]))) {
4428 pReqMsg->buckets[bktIndex].channels[j].
4429 passive = 1;
4430 pReqMsg->buckets[bktIndex].channels[j].
4431 dwellTimeMs = passive_max_chn_time;
4432 } else {
4433 pReqMsg->buckets[bktIndex].channels[j].
4434 passive = 0;
4435 pReqMsg->buckets[bktIndex].channels[j].
4436 dwellTimeMs = active_max_chn_time;
4437 }
4438
4439 hddLog(LOG1,
4440 "Channel %u Passive %u Dwell time %u ms",
4441 pReqMsg->buckets[bktIndex].channels[j].channel,
4442 pReqMsg->buckets[bktIndex].channels[j].passive,
4443 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4444 }
4445
4446 bktIndex++;
4447 continue;
4448 }
4449
4450 /* Parse and fetch number of channels */
4451 if (!bucket[
4452 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4453 hddLog(LOGE, FL("attr num channels failed"));
4454 return -EINVAL;
4455 }
4456
4457 pReqMsg->buckets[bktIndex].numChannels =
4458 nla_get_u32(bucket[
4459 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4460 hddLog(LOG1, FL("num channels %d"),
4461 pReqMsg->buckets[bktIndex].numChannels);
4462
4463 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4464 hddLog(LOGE, FL("attr channel spec failed"));
4465 return -EINVAL;
4466 }
4467
4468 j = 0;
4469 nla_for_each_nested(channels,
4470 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4471 if (nla_parse(channel,
4472 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4473 nla_data(channels), nla_len(channels),
4474 wlan_hdd_extscan_config_policy)) {
4475 hddLog(LOGE, FL("nla_parse failed"));
4476 return -EINVAL;
4477 }
4478
4479 /* Parse and fetch channel */
4480 if (!channel[
4481 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4482 hddLog(LOGE, FL("attr channel failed"));
4483 return -EINVAL;
4484 }
4485 pReqMsg->buckets[bktIndex].channels[j].channel =
4486 nla_get_u32(channel[
4487 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4488 hddLog(LOG1, FL("channel %u"),
4489 pReqMsg->buckets[bktIndex].channels[j].channel);
4490
4491 /* Parse and fetch dwell time */
4492 if (!channel[
4493 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4494 hddLog(LOGE, FL("attr dwelltime failed"));
4495 return -EINVAL;
4496 }
4497 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4498 nla_get_u32(channel[
4499 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4500
4501 hddLog(LOG1, FL("Dwell time (%u ms)"),
4502 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4503
4504
4505 /* Parse and fetch channel spec passive */
4506 if (!channel[
4507 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4508 hddLog(LOGE,
4509 FL("attr channel spec passive failed"));
4510 return -EINVAL;
4511 }
4512 pReqMsg->buckets[bktIndex].channels[j].passive =
4513 nla_get_u8(channel[
4514 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4515 hddLog(LOG1, FL("Chnl spec passive %u"),
4516 pReqMsg->buckets[bktIndex].channels[j].passive);
4517
4518 j++;
4519 }
4520
4521 bktIndex++;
4522 }
4523
4524 return 0;
4525}
4526
4527
4528/*
4529 * define short names for the global vendor params
4530 * used by wlan_hdd_cfg80211_extscan_start()
4531 */
4532#define PARAM_MAX \
4533QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4534#define PARAM_REQUEST_ID \
4535QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4536#define PARAM_BASE_PERIOD \
4537QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4538#define PARAM_MAX_AP_PER_SCAN \
4539QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4540#define PARAM_RPT_THRHLD_PERCENT \
4541QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4542#define PARAM_RPT_THRHLD_NUM_SCANS \
4543QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4544#define PARAM_NUM_BUCKETS \
4545QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4546
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304547static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304548 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304549 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304550{
Dino Myclee8843b32014-07-04 14:21:45 +05304551 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304552 struct net_device *dev = wdev->netdev;
4553 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4554 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4555 struct nlattr *tb[PARAM_MAX + 1];
4556 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304557 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304558 tANI_U32 request_id;
4559 struct hdd_ext_scan_context *context;
4560 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304561
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304562 ENTER();
4563
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304564 if (VOS_FTM_MODE == hdd_get_conparam()) {
4565 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4566 return -EINVAL;
4567 }
4568
Dino Mycle6fb96c12014-06-10 11:52:40 +05304569 status = wlan_hdd_validate_context(pHddCtx);
4570 if (0 != status)
4571 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304572 return -EINVAL;
4573 }
Dino Myclee8843b32014-07-04 14:21:45 +05304574 /* check the EXTScan Capability */
4575 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4576 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4577 {
4578 hddLog(VOS_TRACE_LEVEL_ERROR,
4579 FL("EXTScan not enabled/supported by Firmware"));
4580 return -EINVAL;
4581 }
4582
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304583 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304584 data, dataLen,
4585 wlan_hdd_extscan_config_policy)) {
4586 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4587 return -EINVAL;
4588 }
4589
4590 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304591 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304592 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4593 return -EINVAL;
4594 }
4595
Dino Myclee8843b32014-07-04 14:21:45 +05304596 pReqMsg = (tpSirEXTScanStartReqParams)
4597 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304598 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304599 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4600 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304601 }
4602
4603 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304604 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304605 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4606
4607 pReqMsg->sessionId = pAdapter->sessionId;
4608 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4609
4610 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304611 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304612 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4613 goto fail;
4614 }
4615 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304616 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304617 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4618 pReqMsg->basePeriod);
4619
4620 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304621 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304622 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4623 goto fail;
4624 }
4625 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304626 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304627 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4628 pReqMsg->maxAPperScan);
4629
4630 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304631 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304632 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4633 goto fail;
4634 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304635 pReqMsg->reportThresholdPercent = nla_get_u8(
4636 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304637 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304638 pReqMsg->reportThresholdPercent);
4639
4640 /* Parse and fetch report threshold num scans */
4641 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4642 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4643 goto fail;
4644 }
4645 pReqMsg->reportThresholdNumScans = nla_get_u8(
4646 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4647 hddLog(LOG1, FL("Report Threshold num scans %d"),
4648 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304649
4650 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304651 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304652 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4653 goto fail;
4654 }
4655 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304656 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304657 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4658 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4659 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4660 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4661 }
4662 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4663 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304664
Dino Mycle6fb96c12014-06-10 11:52:40 +05304665 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4666 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4667 goto fail;
4668 }
4669
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304670 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304671
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304672 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4673 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304674
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304675 context = &pHddCtx->ext_scan_context;
4676 spin_lock(&hdd_context_lock);
4677 INIT_COMPLETION(context->response_event);
4678 context->request_id = request_id = pReqMsg->requestId;
4679 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304680
Dino Mycle6fb96c12014-06-10 11:52:40 +05304681 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4682 if (!HAL_STATUS_SUCCESS(status)) {
4683 hddLog(VOS_TRACE_LEVEL_ERROR,
4684 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304685 goto fail;
4686 }
4687
4688 /* request was sent -- wait for the response */
4689 rc = wait_for_completion_timeout(&context->response_event,
4690 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4691
4692 if (!rc) {
4693 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4694 retval = -ETIMEDOUT;
4695 } else {
4696 spin_lock(&hdd_context_lock);
4697 if (context->request_id == request_id)
4698 retval = context->response_status;
4699 else
4700 retval = -EINVAL;
4701 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304702 }
4703
Dino Myclee8843b32014-07-04 14:21:45 +05304704 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304705 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304706 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304707
4708fail:
4709 vos_mem_free(pReqMsg);
4710 return -EINVAL;
4711}
4712
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304713/*
4714 * done with short names for the global vendor params
4715 * used by wlan_hdd_cfg80211_extscan_start()
4716 */
4717#undef PARAM_MAX
4718#undef PARAM_REQUEST_ID
4719#undef PARAM_BASE_PERIOD
4720#undef PARAMS_MAX_AP_PER_SCAN
4721#undef PARAMS_RPT_THRHLD_PERCENT
4722#undef PARAMS_RPT_THRHLD_NUM_SCANS
4723#undef PARAMS_NUM_BUCKETS
4724
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304725static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4726 struct wireless_dev *wdev,
4727 const void *data, int dataLen)
4728{
4729 int ret = 0;
4730
4731 vos_ssr_protect(__func__);
4732 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4733 vos_ssr_unprotect(__func__);
4734
4735 return ret;
4736}
4737
4738static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304739 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304740 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304741{
Dino Myclee8843b32014-07-04 14:21:45 +05304742 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304743 struct net_device *dev = wdev->netdev;
4744 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4745 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4746 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4747 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304748 int retval;
4749 unsigned long rc;
4750 struct hdd_ext_scan_context *context;
4751 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304752
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304753 ENTER();
4754
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304755 if (VOS_FTM_MODE == hdd_get_conparam()) {
4756 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4757 return -EINVAL;
4758 }
4759
Dino Mycle6fb96c12014-06-10 11:52:40 +05304760 status = wlan_hdd_validate_context(pHddCtx);
4761 if (0 != status)
4762 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304763 return -EINVAL;
4764 }
Dino Myclee8843b32014-07-04 14:21:45 +05304765 /* check the EXTScan Capability */
4766 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4767 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4768 {
4769 hddLog(VOS_TRACE_LEVEL_ERROR,
4770 FL("EXTScan not enabled/supported by Firmware"));
4771 return -EINVAL;
4772 }
4773
Dino Mycle6fb96c12014-06-10 11:52:40 +05304774 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4775 data, dataLen,
4776 wlan_hdd_extscan_config_policy)) {
4777 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4778 return -EINVAL;
4779 }
4780
4781 /* Parse and fetch request Id */
4782 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4784 return -EINVAL;
4785 }
4786
Dino Myclee8843b32014-07-04 14:21:45 +05304787 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304788 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304789 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304790
Dino Myclee8843b32014-07-04 14:21:45 +05304791 reqMsg.sessionId = pAdapter->sessionId;
4792 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304793
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304794 context = &pHddCtx->ext_scan_context;
4795 spin_lock(&hdd_context_lock);
4796 INIT_COMPLETION(context->response_event);
4797 context->request_id = request_id = reqMsg.sessionId;
4798 spin_unlock(&hdd_context_lock);
4799
Dino Myclee8843b32014-07-04 14:21:45 +05304800 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304801 if (!HAL_STATUS_SUCCESS(status)) {
4802 hddLog(VOS_TRACE_LEVEL_ERROR,
4803 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304804 return -EINVAL;
4805 }
4806
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304807 /* request was sent -- wait for the response */
4808 rc = wait_for_completion_timeout(&context->response_event,
4809 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4810
4811 if (!rc) {
4812 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4813 retval = -ETIMEDOUT;
4814 } else {
4815 spin_lock(&hdd_context_lock);
4816 if (context->request_id == request_id)
4817 retval = context->response_status;
4818 else
4819 retval = -EINVAL;
4820 spin_unlock(&hdd_context_lock);
4821 }
4822
4823 return retval;
4824
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304825 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304826 return 0;
4827}
4828
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304829static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4830 struct wireless_dev *wdev,
4831 const void *data, int dataLen)
4832{
4833 int ret = 0;
4834
4835 vos_ssr_protect(__func__);
4836 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4837 vos_ssr_unprotect(__func__);
4838
4839 return ret;
4840}
4841
4842static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304843 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304844 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304845{
Dino Myclee8843b32014-07-04 14:21:45 +05304846 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304847 struct net_device *dev = wdev->netdev;
4848 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4849 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4850 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4851 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304852 struct hdd_ext_scan_context *context;
4853 tANI_U32 request_id;
4854 unsigned long rc;
4855 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304856
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304857 ENTER();
4858
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304859 if (VOS_FTM_MODE == hdd_get_conparam()) {
4860 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4861 return -EINVAL;
4862 }
4863
Dino Mycle6fb96c12014-06-10 11:52:40 +05304864 status = wlan_hdd_validate_context(pHddCtx);
4865 if (0 != status)
4866 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304867 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304868 return -EINVAL;
4869 }
Dino Myclee8843b32014-07-04 14:21:45 +05304870 /* check the EXTScan Capability */
4871 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4872 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4873 {
4874 hddLog(VOS_TRACE_LEVEL_ERROR,
4875 FL("EXTScan not enabled/supported by Firmware"));
4876 return -EINVAL;
4877 }
4878
Dino Mycle6fb96c12014-06-10 11:52:40 +05304879 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4880 data, dataLen,
4881 wlan_hdd_extscan_config_policy)) {
4882 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4883 return -EINVAL;
4884 }
4885
4886 /* Parse and fetch request Id */
4887 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4889 return -EINVAL;
4890 }
4891
Dino Myclee8843b32014-07-04 14:21:45 +05304892 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304893 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304894 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304895
Dino Myclee8843b32014-07-04 14:21:45 +05304896 reqMsg.sessionId = pAdapter->sessionId;
4897 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304898
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304899 context = &pHddCtx->ext_scan_context;
4900 spin_lock(&hdd_context_lock);
4901 INIT_COMPLETION(context->response_event);
4902 context->request_id = request_id = reqMsg.requestId;
4903 spin_unlock(&hdd_context_lock);
4904
Dino Myclee8843b32014-07-04 14:21:45 +05304905 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304906 if (!HAL_STATUS_SUCCESS(status)) {
4907 hddLog(VOS_TRACE_LEVEL_ERROR,
4908 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304909 return -EINVAL;
4910 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304911
4912 /* request was sent -- wait for the response */
4913 rc = wait_for_completion_timeout(&context->response_event,
4914 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4915 if (!rc) {
4916 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4917 retval = -ETIMEDOUT;
4918 } else {
4919 spin_lock(&hdd_context_lock);
4920 if (context->request_id == request_id)
4921 retval = context->response_status;
4922 else
4923 retval = -EINVAL;
4924 spin_unlock(&hdd_context_lock);
4925 }
4926
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304927 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304928 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304929}
4930
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304931static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4932 struct wireless_dev *wdev,
4933 const void *data, int dataLen)
4934{
4935 int ret = 0;
4936
4937 vos_ssr_protect(__func__);
4938 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4939 vos_ssr_unprotect(__func__);
4940
4941 return ret;
4942}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304943#endif /* WLAN_FEATURE_EXTSCAN */
4944
Atul Mittal115287b2014-07-08 13:26:33 +05304945/*EXT TDLS*/
4946static const struct nla_policy
4947wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4948{
4949 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4950 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4951 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4952 {.type = NLA_S32 },
4953 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4954 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4955
4956};
4957
4958static const struct nla_policy
4959wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4960{
4961 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4962
4963};
4964
4965static const struct nla_policy
4966wlan_hdd_tdls_config_state_change_policy[
4967 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4968{
4969 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4970 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4971 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304972 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4973 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4974 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304975
4976};
4977
4978static const struct nla_policy
4979wlan_hdd_tdls_config_get_status_policy[
4980 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4981{
4982 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4983 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4984 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304985 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4986 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4987 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304988
4989};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304990
4991static const struct nla_policy
4992wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4993{
4994 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4995};
4996
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304997static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304998 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304999 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305000 int data_len)
5001{
5002
5003 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5004 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5005
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305006 ENTER();
5007
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305008 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305009 return -EINVAL;
5010 }
5011 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305012 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305013 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305014 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305015 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305016 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305017 return -ENOTSUPP;
5018 }
5019
5020 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5021 data, data_len, wlan_hdd_mac_config)) {
5022 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5023 return -EINVAL;
5024 }
5025
5026 /* Parse and fetch mac address */
5027 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5028 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5029 return -EINVAL;
5030 }
5031
5032 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5033 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5034 VOS_MAC_ADDR_LAST_3_BYTES);
5035
Siddharth Bhal76972212014-10-15 16:22:51 +05305036 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5037
5038 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305039 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5040 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305041 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5042 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5043 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5044 {
5045 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5046 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5047 VOS_MAC_ADDRESS_LEN);
5048 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305049 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305050
Siddharth Bhal76972212014-10-15 16:22:51 +05305051 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
5052 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305053 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
5054 }
5055
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305056 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305057 return 0;
5058}
5059
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305060static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5061 struct wireless_dev *wdev,
5062 const void *data,
5063 int data_len)
5064{
5065 int ret = 0;
5066
5067 vos_ssr_protect(__func__);
5068 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5069 vos_ssr_unprotect(__func__);
5070
5071 return ret;
5072}
5073
5074static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305075 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305076 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305077 int data_len)
5078{
5079 u8 peer[6] = {0};
5080 struct net_device *dev = wdev->netdev;
5081 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5082 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5083 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5084 eHalStatus ret;
5085 tANI_S32 state;
5086 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305087 tANI_S32 global_operating_class = 0;
5088 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305089 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305090 int retVal;
5091
5092 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305093
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305094 if (!pAdapter) {
5095 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5096 return -EINVAL;
5097 }
5098
Atul Mittal115287b2014-07-08 13:26:33 +05305099 ret = wlan_hdd_validate_context(pHddCtx);
5100 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305102 return -EINVAL;
5103 }
5104 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305105 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305106 return -ENOTSUPP;
5107 }
5108 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5109 data, data_len,
5110 wlan_hdd_tdls_config_get_status_policy)) {
5111 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5112 return -EINVAL;
5113 }
5114
5115 /* Parse and fetch mac address */
5116 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5117 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5118 return -EINVAL;
5119 }
5120
5121 memcpy(peer, nla_data(
5122 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5123 sizeof(peer));
5124 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5125
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305126 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305127
Atul Mittal115287b2014-07-08 13:26:33 +05305128 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305129 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305130 NLMSG_HDRLEN);
5131
5132 if (!skb) {
5133 hddLog(VOS_TRACE_LEVEL_ERROR,
5134 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5135 return -EINVAL;
5136 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305137 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05305138 reason,
5139 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305140 global_operating_class,
5141 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305142 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305143 if (nla_put_s32(skb,
5144 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5145 state) ||
5146 nla_put_s32(skb,
5147 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5148 reason) ||
5149 nla_put_s32(skb,
5150 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5151 global_operating_class) ||
5152 nla_put_s32(skb,
5153 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5154 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305155
5156 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5157 goto nla_put_failure;
5158 }
5159
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305160 retVal = cfg80211_vendor_cmd_reply(skb);
5161 EXIT();
5162 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305163
5164nla_put_failure:
5165 kfree_skb(skb);
5166 return -EINVAL;
5167}
5168
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305169static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5170 struct wireless_dev *wdev,
5171 const void *data,
5172 int data_len)
5173{
5174 int ret = 0;
5175
5176 vos_ssr_protect(__func__);
5177 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5178 vos_ssr_unprotect(__func__);
5179
5180 return ret;
5181}
5182
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305183static int wlan_hdd_cfg80211_exttdls_callback(
5184#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5185 const tANI_U8* mac,
5186#else
5187 tANI_U8* mac,
5188#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305189 tANI_S32 state,
5190 tANI_S32 reason,
5191 void *ctx)
5192{
5193 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305194 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305195 tANI_S32 global_operating_class = 0;
5196 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305197 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305198
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305199 ENTER();
5200
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305201 if (!pAdapter) {
5202 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5203 return -EINVAL;
5204 }
5205
5206 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305207 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305208 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305209 return -EINVAL;
5210 }
5211
5212 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305213 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305214 return -ENOTSUPP;
5215 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305216 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5217#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5218 NULL,
5219#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305220 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5221 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5222 GFP_KERNEL);
5223
5224 if (!skb) {
5225 hddLog(VOS_TRACE_LEVEL_ERROR,
5226 FL("cfg80211_vendor_event_alloc failed"));
5227 return -EINVAL;
5228 }
5229 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305230 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5231 reason,
5232 state,
5233 global_operating_class,
5234 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305235 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5236 MAC_ADDR_ARRAY(mac));
5237
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305238 if (nla_put(skb,
5239 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5240 VOS_MAC_ADDR_SIZE, mac) ||
5241 nla_put_s32(skb,
5242 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5243 state) ||
5244 nla_put_s32(skb,
5245 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5246 reason) ||
5247 nla_put_s32(skb,
5248 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5249 channel) ||
5250 nla_put_s32(skb,
5251 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5252 global_operating_class)
5253 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305254 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5255 goto nla_put_failure;
5256 }
5257
5258 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305259 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305260 return (0);
5261
5262nla_put_failure:
5263 kfree_skb(skb);
5264 return -EINVAL;
5265}
5266
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305267static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305268 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305269 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305270 int data_len)
5271{
5272 u8 peer[6] = {0};
5273 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305274 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5275 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5276 eHalStatus status;
5277 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305278 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305279 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305280
5281 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305282
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305283 if (!dev) {
5284 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5285 return -EINVAL;
5286 }
5287
5288 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5289 if (!pAdapter) {
5290 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5291 return -EINVAL;
5292 }
5293
Atul Mittal115287b2014-07-08 13:26:33 +05305294 status = wlan_hdd_validate_context(pHddCtx);
5295 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305296 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305297 return -EINVAL;
5298 }
5299 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305300 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305301 return -ENOTSUPP;
5302 }
5303 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5304 data, data_len,
5305 wlan_hdd_tdls_config_enable_policy)) {
5306 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5307 return -EINVAL;
5308 }
5309
5310 /* Parse and fetch mac address */
5311 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5312 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5313 return -EINVAL;
5314 }
5315
5316 memcpy(peer, nla_data(
5317 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5318 sizeof(peer));
5319 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5320
5321 /* Parse and fetch channel */
5322 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5324 return -EINVAL;
5325 }
5326 pReqMsg.channel = nla_get_s32(
5327 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5328 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5329
5330 /* Parse and fetch global operating class */
5331 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5332 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5333 return -EINVAL;
5334 }
5335 pReqMsg.global_operating_class = nla_get_s32(
5336 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5337 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5338 pReqMsg.global_operating_class);
5339
5340 /* Parse and fetch latency ms */
5341 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5342 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5343 return -EINVAL;
5344 }
5345 pReqMsg.max_latency_ms = nla_get_s32(
5346 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5347 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5348 pReqMsg.max_latency_ms);
5349
5350 /* Parse and fetch required bandwidth kbps */
5351 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5352 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5353 return -EINVAL;
5354 }
5355
5356 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5357 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5358 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5359 pReqMsg.min_bandwidth_kbps);
5360
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305361 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305362 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305363 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305364 wlan_hdd_cfg80211_exttdls_callback);
5365
5366 EXIT();
5367 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305368}
5369
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305370static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5371 struct wireless_dev *wdev,
5372 const void *data,
5373 int data_len)
5374{
5375 int ret = 0;
5376
5377 vos_ssr_protect(__func__);
5378 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5379 vos_ssr_unprotect(__func__);
5380
5381 return ret;
5382}
5383
5384static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305385 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305386 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305387 int data_len)
5388{
5389 u8 peer[6] = {0};
5390 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305391 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5392 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5393 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305394 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305395 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305396
5397 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305398
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305399 if (!dev) {
5400 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5401 return -EINVAL;
5402 }
5403
5404 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5405 if (!pAdapter) {
5406 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5407 return -EINVAL;
5408 }
5409
Atul Mittal115287b2014-07-08 13:26:33 +05305410 status = wlan_hdd_validate_context(pHddCtx);
5411 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305412 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305413 return -EINVAL;
5414 }
5415 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305416 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305417 return -ENOTSUPP;
5418 }
5419 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5420 data, data_len,
5421 wlan_hdd_tdls_config_disable_policy)) {
5422 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5423 return -EINVAL;
5424 }
5425 /* Parse and fetch mac address */
5426 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5427 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5428 return -EINVAL;
5429 }
5430
5431 memcpy(peer, nla_data(
5432 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5433 sizeof(peer));
5434 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5435
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305436 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5437
5438 EXIT();
5439 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305440}
5441
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305442static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5443 struct wireless_dev *wdev,
5444 const void *data,
5445 int data_len)
5446{
5447 int ret = 0;
5448
5449 vos_ssr_protect(__func__);
5450 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5451 vos_ssr_unprotect(__func__);
5452
5453 return ret;
5454}
5455
Dasari Srinivas7875a302014-09-26 17:50:57 +05305456static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305457__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305458 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305459 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305460{
5461 struct net_device *dev = wdev->netdev;
5462 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5463 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5464 struct sk_buff *skb = NULL;
5465 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305466 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305467
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305468 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305469
5470 ret = wlan_hdd_validate_context(pHddCtx);
5471 if (0 != ret)
5472 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305473 return ret;
5474 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305475 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5476 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5477 fset |= WIFI_FEATURE_INFRA;
5478 }
5479
5480 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5481 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5482 fset |= WIFI_FEATURE_INFRA_5G;
5483 }
5484
5485#ifdef WLAN_FEATURE_P2P
5486 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5487 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5488 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5489 fset |= WIFI_FEATURE_P2P;
5490 }
5491#endif
5492
5493 /* Soft-AP is supported currently by default */
5494 fset |= WIFI_FEATURE_SOFT_AP;
5495
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305496 /* HOTSPOT is a supplicant feature, enable it by default */
5497 fset |= WIFI_FEATURE_HOTSPOT;
5498
Dasari Srinivas7875a302014-09-26 17:50:57 +05305499#ifdef WLAN_FEATURE_EXTSCAN
5500 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
5501 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
5502 hddLog(LOG1, FL("EXTScan is supported by firmware"));
5503 fset |= WIFI_FEATURE_EXTSCAN;
5504 }
5505#endif
5506
Dasari Srinivas7875a302014-09-26 17:50:57 +05305507 if (sme_IsFeatureSupportedByFW(NAN)) {
5508 hddLog(LOG1, FL("NAN is supported by firmware"));
5509 fset |= WIFI_FEATURE_NAN;
5510 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305511
5512 /* D2D RTT is not supported currently by default */
5513 if (sme_IsFeatureSupportedByFW(RTT)) {
5514 hddLog(LOG1, FL("RTT is supported by firmware"));
5515 fset |= WIFI_FEATURE_D2AP_RTT;
5516 }
5517
5518#ifdef FEATURE_WLAN_BATCH_SCAN
5519 if (fset & WIFI_FEATURE_EXTSCAN) {
5520 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5521 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5522 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5523 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5524 fset |= WIFI_FEATURE_BATCH_SCAN;
5525 }
5526#endif
5527
5528#ifdef FEATURE_WLAN_SCAN_PNO
5529 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5530 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5531 hddLog(LOG1, FL("PNO is supported by firmware"));
5532 fset |= WIFI_FEATURE_PNO;
5533 }
5534#endif
5535
5536 /* STA+STA is supported currently by default */
5537 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5538
5539#ifdef FEATURE_WLAN_TDLS
5540 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5541 sme_IsFeatureSupportedByFW(TDLS)) {
5542 hddLog(LOG1, FL("TDLS is supported by firmware"));
5543 fset |= WIFI_FEATURE_TDLS;
5544 }
5545
5546 /* TDLS_OFFCHANNEL is not supported currently by default */
5547#endif
5548
5549#ifdef WLAN_AP_STA_CONCURRENCY
5550 /* AP+STA concurrency is supported currently by default */
5551 fset |= WIFI_FEATURE_AP_STA;
5552#endif
5553
Mukul Sharma5add0532015-08-17 15:57:47 +05305554#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5555 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5556 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5557#endif
5558
Dasari Srinivas7875a302014-09-26 17:50:57 +05305559 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5560 NLMSG_HDRLEN);
5561
5562 if (!skb) {
5563 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5564 return -EINVAL;
5565 }
5566 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5567
5568 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5569 hddLog(LOGE, FL("nla put fail"));
5570 goto nla_put_failure;
5571 }
5572
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305573 ret = cfg80211_vendor_cmd_reply(skb);
5574 EXIT();
5575 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305576
5577nla_put_failure:
5578 kfree_skb(skb);
5579 return -EINVAL;
5580}
5581
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305582static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305583wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5584 struct wireless_dev *wdev,
5585 const void *data, int data_len)
5586{
5587 int ret = 0;
5588
5589 vos_ssr_protect(__func__);
5590 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5591 vos_ssr_unprotect(__func__);
5592
5593 return ret;
5594}
5595
5596static int
5597__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305598 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305599 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305600{
5601 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5602 uint8_t i, feature_sets, max_feature_sets;
5603 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5604 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305605 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5606 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305607
5608 ENTER();
5609
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305610 ret = wlan_hdd_validate_context(pHddCtx);
5611 if (0 != ret)
5612 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305613 return ret;
5614 }
5615
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305616 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5617 data, data_len, NULL)) {
5618 hddLog(LOGE, FL("Invalid ATTR"));
5619 return -EINVAL;
5620 }
5621
5622 /* Parse and fetch max feature set */
5623 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5624 hddLog(LOGE, FL("Attr max feature set size failed"));
5625 return -EINVAL;
5626 }
5627 max_feature_sets = nla_get_u32(
5628 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5629 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5630
5631 /* Fill feature combination matrix */
5632 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305633 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5634 WIFI_FEATURE_P2P;
5635
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305636 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5637 WIFI_FEATURE_SOFT_AP;
5638
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305639 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5640 WIFI_FEATURE_SOFT_AP;
5641
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305642 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5643 WIFI_FEATURE_SOFT_AP |
5644 WIFI_FEATURE_P2P;
5645
5646 /* Add more feature combinations here */
5647
5648 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5649 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5650 hddLog(LOG1, "Feature set matrix");
5651 for (i = 0; i < feature_sets; i++)
5652 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5653
5654 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5655 sizeof(u32) * feature_sets +
5656 NLMSG_HDRLEN);
5657
5658 if (reply_skb) {
5659 if (nla_put_u32(reply_skb,
5660 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5661 feature_sets) ||
5662 nla_put(reply_skb,
5663 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5664 sizeof(u32) * feature_sets, feature_set_matrix)) {
5665 hddLog(LOGE, FL("nla put fail"));
5666 kfree_skb(reply_skb);
5667 return -EINVAL;
5668 }
5669
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305670 ret = cfg80211_vendor_cmd_reply(reply_skb);
5671 EXIT();
5672 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305673 }
5674 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5675 return -ENOMEM;
5676
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305677}
5678
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305679static int
5680wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5681 struct wireless_dev *wdev,
5682 const void *data, int data_len)
5683{
5684 int ret = 0;
5685
5686 vos_ssr_protect(__func__);
5687 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5688 data_len);
5689 vos_ssr_unprotect(__func__);
5690
5691 return ret;
5692}
5693
Agarwal Ashish738843c2014-09-25 12:27:56 +05305694static const struct nla_policy
5695wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5696 +1] =
5697{
5698 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5699};
5700
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305701static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305702 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305703 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305704 int data_len)
5705{
5706 struct net_device *dev = wdev->netdev;
5707 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5708 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5709 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5710 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5711 eHalStatus status;
5712 u32 dfsFlag = 0;
5713
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305714 ENTER();
5715
Agarwal Ashish738843c2014-09-25 12:27:56 +05305716 status = wlan_hdd_validate_context(pHddCtx);
5717 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305718 return -EINVAL;
5719 }
5720 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5721 data, data_len,
5722 wlan_hdd_set_no_dfs_flag_config_policy)) {
5723 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5724 return -EINVAL;
5725 }
5726
5727 /* Parse and fetch required bandwidth kbps */
5728 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5729 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5730 return -EINVAL;
5731 }
5732
5733 dfsFlag = nla_get_u32(
5734 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5735 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5736 dfsFlag);
5737
5738 pHddCtx->disable_dfs_flag = dfsFlag;
5739
5740 sme_disable_dfs_channel(hHal, dfsFlag);
5741 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305742
5743 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305744 return 0;
5745}
Atul Mittal115287b2014-07-08 13:26:33 +05305746
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305747static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5748 struct wireless_dev *wdev,
5749 const void *data,
5750 int data_len)
5751{
5752 int ret = 0;
5753
5754 vos_ssr_protect(__func__);
5755 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5756 vos_ssr_unprotect(__func__);
5757
5758 return ret;
5759
5760}
5761
Mukul Sharma2a271632014-10-13 14:59:01 +05305762const struct
5763nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5764{
5765 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5766 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5767};
5768
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305769static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305770 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305771{
5772
5773 u8 bssid[6] = {0};
5774 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5775 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5776 eHalStatus status = eHAL_STATUS_SUCCESS;
5777 v_U32_t isFwrRoamEnabled = FALSE;
5778 int ret;
5779
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305780 ENTER();
5781
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305782 ret = wlan_hdd_validate_context(pHddCtx);
5783 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305784 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305785 }
5786
5787 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5788 data, data_len,
5789 qca_wlan_vendor_attr);
5790 if (ret){
5791 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5792 return -EINVAL;
5793 }
5794
5795 /* Parse and fetch Enable flag */
5796 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5798 return -EINVAL;
5799 }
5800
5801 isFwrRoamEnabled = nla_get_u32(
5802 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5803
5804 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5805
5806 /* Parse and fetch bssid */
5807 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5808 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5809 return -EINVAL;
5810 }
5811
5812 memcpy(bssid, nla_data(
5813 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5814 sizeof(bssid));
5815 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5816
5817 //Update roaming
5818 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305819 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305820 return status;
5821}
5822
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305823static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5824 struct wireless_dev *wdev, const void *data, int data_len)
5825{
5826 int ret = 0;
5827
5828 vos_ssr_protect(__func__);
5829 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5830 vos_ssr_unprotect(__func__);
5831
5832 return ret;
5833}
5834
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305835/**
5836 * __wlan_hdd_cfg80211_setband() - set band
5837 * @wiphy: Pointer to wireless phy
5838 * @wdev: Pointer to wireless device
5839 * @data: Pointer to data
5840 * @data_len: Data length
5841 *
5842 * Return: 0 on success, negative errno on failure
5843 */
5844static int
5845__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5846 struct wireless_dev *wdev,
5847 const void *data,
5848 int data_len)
5849{
5850 struct net_device *dev = wdev->netdev;
5851 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5852 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5853 int ret;
5854 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
5855 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
5856
5857 ENTER();
5858
5859 ret = wlan_hdd_validate_context(hdd_ctx);
5860 if (0 != ret) {
5861 hddLog(LOGE, FL("HDD context is not valid"));
5862 return ret;
5863 }
5864
5865 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
5866 policy)) {
5867 hddLog(LOGE, FL("Invalid ATTR"));
5868 return -EINVAL;
5869 }
5870
5871 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
5872 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
5873 return -EINVAL;
5874 }
5875
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305876 hdd_ctx->isSetBandByNL = TRUE;
5877 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305878 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305879 hdd_ctx->isSetBandByNL = FALSE;
5880
5881 EXIT();
5882 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305883}
5884
5885/**
5886 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
5887 * @wiphy: wiphy structure pointer
5888 * @wdev: Wireless device structure pointer
5889 * @data: Pointer to the data received
5890 * @data_len: Length of @data
5891 *
5892 * Return: 0 on success; errno on failure
5893 */
5894static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5895 struct wireless_dev *wdev,
5896 const void *data,
5897 int data_len)
5898{
5899 int ret = 0;
5900
5901 vos_ssr_protect(__func__);
5902 ret = __wlan_hdd_cfg80211_setband(wiphy,
5903 wdev, data, data_len);
5904 vos_ssr_unprotect(__func__);
5905
5906 return ret;
5907}
5908
Sunil Duttc69bccb2014-05-26 21:30:20 +05305909const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
5910{
Mukul Sharma2a271632014-10-13 14:59:01 +05305911 {
5912 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5913 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
5914 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5915 WIPHY_VENDOR_CMD_NEED_NETDEV |
5916 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305917 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05305918 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305919
5920 {
5921 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5922 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
5923 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5924 WIPHY_VENDOR_CMD_NEED_NETDEV |
5925 WIPHY_VENDOR_CMD_NEED_RUNNING,
5926 .doit = wlan_hdd_cfg80211_nan_request
5927 },
5928
Sunil Duttc69bccb2014-05-26 21:30:20 +05305929#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5930 {
5931 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5932 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
5933 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5934 WIPHY_VENDOR_CMD_NEED_NETDEV |
5935 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305936 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05305937 },
5938
5939 {
5940 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5941 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
5942 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5943 WIPHY_VENDOR_CMD_NEED_NETDEV |
5944 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305945 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05305946 },
5947
5948 {
5949 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5950 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
5951 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5952 WIPHY_VENDOR_CMD_NEED_NETDEV |
5953 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305954 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05305955 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305956#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305957#ifdef WLAN_FEATURE_EXTSCAN
5958 {
5959 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5960 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
5961 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5962 WIPHY_VENDOR_CMD_NEED_NETDEV |
5963 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305964 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05305965 },
5966 {
5967 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5968 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
5969 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5970 WIPHY_VENDOR_CMD_NEED_NETDEV |
5971 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305972 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05305973 },
5974 {
5975 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5976 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
5977 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5978 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305979 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05305980 },
5981 {
5982 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5983 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
5984 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5985 WIPHY_VENDOR_CMD_NEED_NETDEV |
5986 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305987 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05305988 },
5989 {
5990 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5991 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
5992 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5993 WIPHY_VENDOR_CMD_NEED_NETDEV |
5994 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305995 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05305996 },
5997 {
5998 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5999 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
6000 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6001 WIPHY_VENDOR_CMD_NEED_NETDEV |
6002 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306003 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05306004 },
6005 {
6006 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6007 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
6008 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6009 WIPHY_VENDOR_CMD_NEED_NETDEV |
6010 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306011 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05306012 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05306013 {
6014 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6015 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
6016 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6017 WIPHY_VENDOR_CMD_NEED_NETDEV |
6018 WIPHY_VENDOR_CMD_NEED_RUNNING,
6019 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
6020 },
6021 {
6022 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6023 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
6024 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6025 WIPHY_VENDOR_CMD_NEED_NETDEV |
6026 WIPHY_VENDOR_CMD_NEED_RUNNING,
6027 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
6028 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05306029#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05306030/*EXT TDLS*/
6031 {
6032 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6033 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
6034 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6035 WIPHY_VENDOR_CMD_NEED_NETDEV |
6036 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306037 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05306038 },
6039 {
6040 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6041 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
6042 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6043 WIPHY_VENDOR_CMD_NEED_NETDEV |
6044 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306045 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05306046 },
6047 {
6048 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6049 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
6050 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6051 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306052 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05306053 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05306054 {
6055 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6056 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
6057 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6058 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306059 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05306060 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05306061 {
6062 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6063 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
6064 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6065 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306066 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05306067 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05306068 {
6069 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6070 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
6071 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6072 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306073 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05306074 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306075 {
6076 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6077 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
6078 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6079 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306080 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306081 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306082 {
6083 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6084 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
6085 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6086 WIPHY_VENDOR_CMD_NEED_NETDEV |
6087 WIPHY_VENDOR_CMD_NEED_RUNNING,
6088 .doit = wlan_hdd_cfg80211_setband
6089 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05306090};
6091
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006092/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05306093static const
6094struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006095{
6096#ifdef FEATURE_WLAN_CH_AVOID
6097 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05306098 .vendor_id = QCA_NL80211_VENDOR_ID,
6099 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006100 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05306101#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
6102#ifdef WLAN_FEATURE_LINK_LAYER_STATS
6103 {
6104 /* Index = 1*/
6105 .vendor_id = QCA_NL80211_VENDOR_ID,
6106 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
6107 },
6108 {
6109 /* Index = 2*/
6110 .vendor_id = QCA_NL80211_VENDOR_ID,
6111 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
6112 },
6113 {
6114 /* Index = 3*/
6115 .vendor_id = QCA_NL80211_VENDOR_ID,
6116 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
6117 },
6118 {
6119 /* Index = 4*/
6120 .vendor_id = QCA_NL80211_VENDOR_ID,
6121 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
6122 },
6123 {
6124 /* Index = 5*/
6125 .vendor_id = QCA_NL80211_VENDOR_ID,
6126 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
6127 },
6128 {
6129 /* Index = 6*/
6130 .vendor_id = QCA_NL80211_VENDOR_ID,
6131 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
6132 },
6133#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05306134#ifdef WLAN_FEATURE_EXTSCAN
6135 {
6136 .vendor_id = QCA_NL80211_VENDOR_ID,
6137 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
6138 },
6139 {
6140 .vendor_id = QCA_NL80211_VENDOR_ID,
6141 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
6142 },
6143 {
6144 .vendor_id = QCA_NL80211_VENDOR_ID,
6145 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
6146 },
6147 {
6148 .vendor_id = QCA_NL80211_VENDOR_ID,
6149 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
6150 },
6151 {
6152 .vendor_id = QCA_NL80211_VENDOR_ID,
6153 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
6154 },
6155 {
6156 .vendor_id = QCA_NL80211_VENDOR_ID,
6157 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
6158 },
6159 {
6160 .vendor_id = QCA_NL80211_VENDOR_ID,
6161 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
6162 },
6163 {
6164 .vendor_id = QCA_NL80211_VENDOR_ID,
6165 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
6166 },
6167 {
6168 .vendor_id = QCA_NL80211_VENDOR_ID,
6169 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
6170 },
6171 {
6172 .vendor_id = QCA_NL80211_VENDOR_ID,
6173 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
6174 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05306175 {
6176 .vendor_id = QCA_NL80211_VENDOR_ID,
6177 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
6178 },
6179 {
6180 .vendor_id = QCA_NL80211_VENDOR_ID,
6181 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
6182 },
6183 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
6184 .vendor_id = QCA_NL80211_VENDOR_ID,
6185 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
6186 },
6187 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
6188 .vendor_id = QCA_NL80211_VENDOR_ID,
6189 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
6190 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05306191#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05306192/*EXT TDLS*/
6193 {
6194 .vendor_id = QCA_NL80211_VENDOR_ID,
6195 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
6196 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05306197
6198 {
6199 .vendor_id = QCA_NL80211_VENDOR_ID,
6200 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
6201 },
6202
Sushant Kaushik084f6592015-09-10 13:11:56 +05306203 {
6204 .vendor_id = QCA_NL80211_VENDOR_ID,
6205 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
6206 }
6207
6208
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006209};
6210
Jeff Johnson295189b2012-06-20 16:38:30 -07006211/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306212 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306213 * This function is called by hdd_wlan_startup()
6214 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306215 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07006216 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306217struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07006218{
6219 struct wiphy *wiphy;
6220 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306221 /*
6222 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07006223 */
6224 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
6225
6226 if (!wiphy)
6227 {
6228 /* Print error and jump into err label and free the memory */
6229 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
6230 return NULL;
6231 }
6232
Sunil Duttc69bccb2014-05-26 21:30:20 +05306233
Jeff Johnson295189b2012-06-20 16:38:30 -07006234 return wiphy;
6235}
6236
6237/*
6238 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306239 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07006240 * private ioctl to change the band value
6241 */
6242int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
6243{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306244 int i, j;
6245 eNVChannelEnabledType channelEnabledState;
6246
Jeff Johnsone7245742012-09-05 17:12:55 -07006247 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306248
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306249 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006250 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306251
6252 if (NULL == wiphy->bands[i])
6253 {
6254 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
6255 __func__, i);
6256 continue;
6257 }
6258
6259 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6260 {
6261 struct ieee80211_supported_band *band = wiphy->bands[i];
6262
6263 channelEnabledState = vos_nv_getChannelEnabledState(
6264 band->channels[j].hw_value);
6265
6266 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
6267 {
Abhishek Singh678227a2014-11-04 10:52:38 +05306268 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306269 continue;
6270 }
6271 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
6272 {
6273 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6274 continue;
6275 }
6276
6277 if (NV_CHANNEL_DISABLE == channelEnabledState ||
6278 NV_CHANNEL_INVALID == channelEnabledState)
6279 {
6280 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6281 }
6282 else if (NV_CHANNEL_DFS == channelEnabledState)
6283 {
6284 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6285 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
6286 }
6287 else
6288 {
6289 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
6290 |IEEE80211_CHAN_RADAR);
6291 }
6292 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006293 }
6294 return 0;
6295}
6296/*
6297 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306298 * This function is called by hdd_wlan_startup()
6299 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07006300 * This function is used to initialize and register wiphy structure.
6301 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306302int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006303 struct wiphy *wiphy,
6304 hdd_config_t *pCfg
6305 )
6306{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306307 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05306308 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6309
Jeff Johnsone7245742012-09-05 17:12:55 -07006310 ENTER();
6311
Jeff Johnson295189b2012-06-20 16:38:30 -07006312 /* Now bind the underlying wlan device with wiphy */
6313 set_wiphy_dev(wiphy, dev);
6314
6315 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07006316
Kiet Lam6c583332013-10-14 05:37:09 +05306317#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07006318 /* the flag for the other case would be initialzed in
6319 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07006320 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05306321#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07006322
Amar Singhalfddc28c2013-09-05 13:03:40 -07006323 /* This will disable updating of NL channels from passive to
6324 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306325#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6326 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
6327#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07006328 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306329#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07006330
Amar Singhala49cbc52013-10-08 18:37:44 -07006331
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006332#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07006333 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
6334 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
6335 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07006336 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306337#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6338 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
6339#else
6340 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
6341#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006342#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07006343
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006344#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006345 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08006346#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006347 || pCfg->isFastRoamIniFeatureEnabled
6348#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006349#ifdef FEATURE_WLAN_ESE
6350 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006351#endif
6352 )
6353 {
6354 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
6355 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08006356#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006357#ifdef FEATURE_WLAN_TDLS
6358 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
6359 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
6360#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306361#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05306362 if (pCfg->configPNOScanSupport)
6363 {
6364 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
6365 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
6366 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
6367 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
6368 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306369#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006370
Abhishek Singh10d85972015-04-17 10:27:23 +05306371#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6372 wiphy->features |= NL80211_FEATURE_HT_IBSS;
6373#endif
6374
Amar Singhalfddc28c2013-09-05 13:03:40 -07006375#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006376 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
6377 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07006378 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006379 driver need to determine what to do with both
6380 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07006381
6382 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07006383#else
6384 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07006385#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006386
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306387 wiphy->max_scan_ssids = MAX_SCAN_SSID;
6388
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05306389 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07006390
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306391 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
6392
Jeff Johnson295189b2012-06-20 16:38:30 -07006393 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05306394 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
6395 | BIT(NL80211_IFTYPE_ADHOC)
6396 | BIT(NL80211_IFTYPE_P2P_CLIENT)
6397 | BIT(NL80211_IFTYPE_P2P_GO)
6398 | BIT(NL80211_IFTYPE_AP);
6399
6400 if (VOS_MONITOR_MODE == hdd_get_conparam())
6401 {
6402 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
6403 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006404
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306405 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006406 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306407#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6408 if( pCfg->enableMCC )
6409 {
6410 /* Currently, supports up to two channels */
6411 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006412
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306413 if( !pCfg->allowMCCGODiffBI )
6414 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006415
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306416 }
6417 wiphy->iface_combinations = &wlan_hdd_iface_combination;
6418 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006419#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306420 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006421
Jeff Johnson295189b2012-06-20 16:38:30 -07006422 /* Before registering we need to update the ht capabilitied based
6423 * on ini values*/
6424 if( !pCfg->ShortGI20MhzEnable )
6425 {
6426 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6427 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6428 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6429 }
6430
6431 if( !pCfg->ShortGI40MhzEnable )
6432 {
6433 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
6434 }
6435
6436 if( !pCfg->nChannelBondingMode5GHz )
6437 {
6438 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6439 }
6440
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306441 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05306442 if (true == hdd_is_5g_supported(pHddCtx))
6443 {
6444 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
6445 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306446
6447 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
6448 {
6449
6450 if (NULL == wiphy->bands[i])
6451 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05306452 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306453 __func__, i);
6454 continue;
6455 }
6456
6457 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6458 {
6459 struct ieee80211_supported_band *band = wiphy->bands[i];
6460
6461 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
6462 {
6463 // Enable social channels for P2P
6464 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
6465 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6466 else
6467 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6468 continue;
6469 }
6470 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
6471 {
6472 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6473 continue;
6474 }
6475 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006476 }
6477 /*Initialise the supported cipher suite details*/
6478 wiphy->cipher_suites = hdd_cipher_suites;
6479 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
6480
6481 /*signal strength in mBm (100*dBm) */
6482 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
6483
6484#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05306485 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07006486#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006487
Sunil Duttc69bccb2014-05-26 21:30:20 +05306488 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
6489 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006490 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
6491 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
6492
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306493 EXIT();
6494 return 0;
6495}
6496
6497/* In this function we are registering wiphy. */
6498int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
6499{
6500 ENTER();
6501 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006502 if (0 > wiphy_register(wiphy))
6503 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306504 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07006505 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
6506 return -EIO;
6507 }
6508
6509 EXIT();
6510 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306511}
Jeff Johnson295189b2012-06-20 16:38:30 -07006512
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306513/* In this function we are updating channel list when,
6514 regulatory domain is FCC and country code is US.
6515 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
6516 As per FCC smart phone is not a indoor device.
6517 GO should not opeate on indoor channels */
6518void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
6519{
6520 int j;
6521 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6522 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
6523 //Default counrtycode from NV at the time of wiphy initialization.
6524 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
6525 &defaultCountryCode[0]))
6526 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006527 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306528 }
6529 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
6530 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306531 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
6532 {
6533 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
6534 return;
6535 }
6536 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
6537 {
6538 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
6539 // Mark UNII -1 band channel as passive
6540 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
6541 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
6542 }
6543 }
6544}
6545
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306546/* This function registers for all frame which supplicant is interested in */
6547void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006548{
Jeff Johnson295189b2012-06-20 16:38:30 -07006549 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6550 /* Register for all P2P action, public action etc frames */
6551 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6552
Jeff Johnsone7245742012-09-05 17:12:55 -07006553 ENTER();
6554
Jeff Johnson295189b2012-06-20 16:38:30 -07006555 /* Right now we are registering these frame when driver is getting
6556 initialized. Once we will move to 2.6.37 kernel, in which we have
6557 frame register ops, we will move this code as a part of that */
6558 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306559 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006560 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6561
6562 /* GAS Initial Response */
6563 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6564 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306565
Jeff Johnson295189b2012-06-20 16:38:30 -07006566 /* GAS Comeback Request */
6567 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6568 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6569
6570 /* GAS Comeback Response */
6571 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6572 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6573
6574 /* P2P Public Action */
6575 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306576 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006577 P2P_PUBLIC_ACTION_FRAME_SIZE );
6578
6579 /* P2P Action */
6580 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6581 (v_U8_t*)P2P_ACTION_FRAME,
6582 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07006583
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05306584 /* WNM BSS Transition Request frame */
6585 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6586 (v_U8_t*)WNM_BSS_ACTION_FRAME,
6587 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006588
6589 /* WNM-Notification */
6590 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6591 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6592 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006593}
6594
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306595void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006596{
Jeff Johnson295189b2012-06-20 16:38:30 -07006597 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6598 /* Register for all P2P action, public action etc frames */
6599 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6600
Jeff Johnsone7245742012-09-05 17:12:55 -07006601 ENTER();
6602
Jeff Johnson295189b2012-06-20 16:38:30 -07006603 /* Right now we are registering these frame when driver is getting
6604 initialized. Once we will move to 2.6.37 kernel, in which we have
6605 frame register ops, we will move this code as a part of that */
6606 /* GAS Initial Request */
6607
6608 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6609 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6610
6611 /* GAS Initial Response */
6612 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6613 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306614
Jeff Johnson295189b2012-06-20 16:38:30 -07006615 /* GAS Comeback Request */
6616 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6617 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6618
6619 /* GAS Comeback Response */
6620 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6621 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6622
6623 /* P2P Public Action */
6624 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306625 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006626 P2P_PUBLIC_ACTION_FRAME_SIZE );
6627
6628 /* P2P Action */
6629 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6630 (v_U8_t*)P2P_ACTION_FRAME,
6631 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006632 /* WNM-Notification */
6633 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6634 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6635 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006636}
6637
6638#ifdef FEATURE_WLAN_WAPI
6639void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05306640 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006641{
6642 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6643 tCsrRoamSetKey setKey;
6644 v_BOOL_t isConnected = TRUE;
6645 int status = 0;
6646 v_U32_t roamId= 0xFF;
6647 tANI_U8 *pKeyPtr = NULL;
6648 int n = 0;
6649
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306650 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6651 __func__, hdd_device_modetoString(pAdapter->device_mode),
6652 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006653
Gopichand Nakkalae7480202013-02-11 15:24:22 +05306654 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006655 setKey.keyId = key_index; // Store Key ID
6656 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
6657 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
6658 setKey.paeRole = 0 ; // the PAE role
6659 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
6660 {
6661 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
6662 }
6663 else
6664 {
6665 isConnected = hdd_connIsConnected(pHddStaCtx);
6666 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
6667 }
6668 setKey.keyLength = key_Len;
6669 pKeyPtr = setKey.Key;
6670 memcpy( pKeyPtr, key, key_Len);
6671
Arif Hussain6d2a3322013-11-17 19:50:10 -08006672 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07006673 __func__, key_Len);
6674 for (n = 0 ; n < key_Len; n++)
6675 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
6676 __func__,n,setKey.Key[n]);
6677
6678 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
6679 if ( isConnected )
6680 {
6681 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
6682 pAdapter->sessionId, &setKey, &roamId );
6683 }
6684 if ( status != 0 )
6685 {
6686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6687 "[%4d] sme_RoamSetKey returned ERROR status= %d",
6688 __LINE__, status );
6689 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
6690 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05306691 /* Need to clear any trace of key value in the memory.
6692 * Thus zero out the memory even though it is local
6693 * variable.
6694 */
6695 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006696}
6697#endif /* FEATURE_WLAN_WAPI*/
6698
6699#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306700int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006701 beacon_data_t **ppBeacon,
6702 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006703#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306704int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006705 beacon_data_t **ppBeacon,
6706 struct cfg80211_beacon_data *params,
6707 int dtim_period)
6708#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306709{
Jeff Johnson295189b2012-06-20 16:38:30 -07006710 int size;
6711 beacon_data_t *beacon = NULL;
6712 beacon_data_t *old = NULL;
6713 int head_len,tail_len;
6714
Jeff Johnsone7245742012-09-05 17:12:55 -07006715 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006716 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306717 {
6718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6719 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006720 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306721 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006722
6723 old = pAdapter->sessionCtx.ap.beacon;
6724
6725 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306726 {
6727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6728 FL("session(%d) old and new heads points to NULL"),
6729 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006730 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306731 }
6732
6733 if (params->tail && !params->tail_len)
6734 {
6735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6736 FL("tail_len is zero but tail is not NULL"));
6737 return -EINVAL;
6738 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006739
Jeff Johnson295189b2012-06-20 16:38:30 -07006740#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
6741 /* Kernel 3.0 is not updating dtim_period for set beacon */
6742 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306743 {
6744 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6745 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006746 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306747 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006748#endif
6749
6750 if(params->head)
6751 head_len = params->head_len;
6752 else
6753 head_len = old->head_len;
6754
6755 if(params->tail || !old)
6756 tail_len = params->tail_len;
6757 else
6758 tail_len = old->tail_len;
6759
6760 size = sizeof(beacon_data_t) + head_len + tail_len;
6761
6762 beacon = kzalloc(size, GFP_KERNEL);
6763
6764 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306765 {
6766 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6767 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006768 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306769 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006770
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006771#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006772 if(params->dtim_period || !old )
6773 beacon->dtim_period = params->dtim_period;
6774 else
6775 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006776#else
6777 if(dtim_period || !old )
6778 beacon->dtim_period = dtim_period;
6779 else
6780 beacon->dtim_period = old->dtim_period;
6781#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306782
Jeff Johnson295189b2012-06-20 16:38:30 -07006783 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6784 beacon->tail = beacon->head + head_len;
6785 beacon->head_len = head_len;
6786 beacon->tail_len = tail_len;
6787
6788 if(params->head) {
6789 memcpy (beacon->head,params->head,beacon->head_len);
6790 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306791 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006792 if(old)
6793 memcpy (beacon->head,old->head,beacon->head_len);
6794 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306795
Jeff Johnson295189b2012-06-20 16:38:30 -07006796 if(params->tail) {
6797 memcpy (beacon->tail,params->tail,beacon->tail_len);
6798 }
6799 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306800 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006801 memcpy (beacon->tail,old->tail,beacon->tail_len);
6802 }
6803
6804 *ppBeacon = beacon;
6805
6806 kfree(old);
6807
6808 return 0;
6809
6810}
Jeff Johnson295189b2012-06-20 16:38:30 -07006811
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306812v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
6813#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6814 const v_U8_t *pIes,
6815#else
6816 v_U8_t *pIes,
6817#endif
6818 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006819{
6820 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306821 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07006822 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306823
Jeff Johnson295189b2012-06-20 16:38:30 -07006824 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306825 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006826 elem_id = ptr[0];
6827 elem_len = ptr[1];
6828 left -= 2;
6829 if(elem_len > left)
6830 {
6831 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006832 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006833 eid,elem_len,left);
6834 return NULL;
6835 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306836 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006837 {
6838 return ptr;
6839 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306840
Jeff Johnson295189b2012-06-20 16:38:30 -07006841 left -= elem_len;
6842 ptr += (elem_len + 2);
6843 }
6844 return NULL;
6845}
6846
Jeff Johnson295189b2012-06-20 16:38:30 -07006847/* Check if rate is 11g rate or not */
6848static int wlan_hdd_rate_is_11g(u8 rate)
6849{
Sanjay Devnani28322e22013-06-21 16:13:40 -07006850 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006851 u8 i;
6852 for (i = 0; i < 8; i++)
6853 {
6854 if(rate == gRateArray[i])
6855 return TRUE;
6856 }
6857 return FALSE;
6858}
6859
6860/* Check for 11g rate and set proper 11g only mode */
6861static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
6862 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
6863{
6864 u8 i, num_rates = pIe[0];
6865
6866 pIe += 1;
6867 for ( i = 0; i < num_rates; i++)
6868 {
6869 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
6870 {
6871 /* If rate set have 11g rate than change the mode to 11G */
6872 *pSapHw_mode = eSAP_DOT11_MODE_11g;
6873 if (pIe[i] & BASIC_RATE_MASK)
6874 {
6875 /* If we have 11g rate as basic rate, it means mode
6876 is 11g only mode.
6877 */
6878 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
6879 *pCheckRatesfor11g = FALSE;
6880 }
6881 }
6882 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6883 {
6884 *require_ht = TRUE;
6885 }
6886 }
6887 return;
6888}
6889
6890static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
6891{
6892 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6893 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6894 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6895 u8 checkRatesfor11g = TRUE;
6896 u8 require_ht = FALSE;
6897 u8 *pIe=NULL;
6898
6899 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
6900
6901 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6902 pBeacon->head_len, WLAN_EID_SUPP_RATES);
6903 if (pIe != NULL)
6904 {
6905 pIe += 1;
6906 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6907 &pConfig->SapHw_mode);
6908 }
6909
6910 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6911 WLAN_EID_EXT_SUPP_RATES);
6912 if (pIe != NULL)
6913 {
6914
6915 pIe += 1;
6916 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6917 &pConfig->SapHw_mode);
6918 }
6919
6920 if( pConfig->channel > 14 )
6921 {
6922 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
6923 }
6924
6925 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6926 WLAN_EID_HT_CAPABILITY);
6927
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306928 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006929 {
6930 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
6931 if(require_ht)
6932 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
6933 }
6934}
6935
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306936static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
6937 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
6938{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006939 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306940 v_U8_t *pIe = NULL;
6941 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6942
6943 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6944 pBeacon->tail, pBeacon->tail_len);
6945
6946 if (pIe)
6947 {
6948 ielen = pIe[1] + 2;
6949 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6950 {
6951 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
6952 }
6953 else
6954 {
6955 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
6956 return -EINVAL;
6957 }
6958 *total_ielen += ielen;
6959 }
6960 return 0;
6961}
6962
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006963static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
6964 v_U8_t *genie, v_U8_t *total_ielen)
6965{
6966 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6967 int left = pBeacon->tail_len;
6968 v_U8_t *ptr = pBeacon->tail;
6969 v_U8_t elem_id, elem_len;
6970 v_U16_t ielen = 0;
6971
6972 if ( NULL == ptr || 0 == left )
6973 return;
6974
6975 while (left >= 2)
6976 {
6977 elem_id = ptr[0];
6978 elem_len = ptr[1];
6979 left -= 2;
6980 if (elem_len > left)
6981 {
6982 hddLog( VOS_TRACE_LEVEL_ERROR,
6983 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
6984 elem_id, elem_len, left);
6985 return;
6986 }
6987 if (IE_EID_VENDOR == elem_id)
6988 {
6989 /* skipping the VSIE's which we don't want to include or
6990 * it will be included by existing code
6991 */
6992 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
6993#ifdef WLAN_FEATURE_WFD
6994 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
6995#endif
6996 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6997 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6998 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
6999 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7000 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
7001 {
7002 ielen = ptr[1] + 2;
7003 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
7004 {
7005 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
7006 *total_ielen += ielen;
7007 }
7008 else
7009 {
7010 hddLog( VOS_TRACE_LEVEL_ERROR,
7011 "IE Length is too big "
7012 "IEs eid=%d elem_len=%d total_ie_lent=%d",
7013 elem_id, elem_len, *total_ielen);
7014 }
7015 }
7016 }
7017
7018 left -= elem_len;
7019 ptr += (elem_len + 2);
7020 }
7021 return;
7022}
7023
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007024#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007025static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
7026 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007027#else
7028static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
7029 struct cfg80211_beacon_data *params)
7030#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007031{
7032 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307033 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007034 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07007035 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007036
7037 genie = vos_mem_malloc(MAX_GENIE_LEN);
7038
7039 if(genie == NULL) {
7040
7041 return -ENOMEM;
7042 }
7043
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307044 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7045 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007046 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307047 hddLog(LOGE,
7048 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307049 ret = -EINVAL;
7050 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007051 }
7052
7053#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307054 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7055 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
7056 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307057 hddLog(LOGE,
7058 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307059 ret = -EINVAL;
7060 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007061 }
7062#endif
7063
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307064 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7065 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007066 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307067 hddLog(LOGE,
7068 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307069 ret = -EINVAL;
7070 goto done;
7071 }
7072
7073 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
7074 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007075 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07007076 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007077
7078 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7079 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
7080 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
7081 {
7082 hddLog(LOGE,
7083 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007084 ret = -EINVAL;
7085 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007086 }
7087
7088 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7089 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
7090 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7091 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7092 ==eHAL_STATUS_FAILURE)
7093 {
7094 hddLog(LOGE,
7095 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007096 ret = -EINVAL;
7097 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007098 }
7099
7100 // Added for ProResp IE
7101 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
7102 {
7103 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
7104 u8 probe_rsp_ie_len[3] = {0};
7105 u8 counter = 0;
7106 /* Check Probe Resp Length if it is greater then 255 then Store
7107 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
7108 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
7109 Store More then 255 bytes into One Variable.
7110 */
7111 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
7112 {
7113 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
7114 {
7115 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
7116 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
7117 }
7118 else
7119 {
7120 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
7121 rem_probe_resp_ie_len = 0;
7122 }
7123 }
7124
7125 rem_probe_resp_ie_len = 0;
7126
7127 if (probe_rsp_ie_len[0] > 0)
7128 {
7129 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7130 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
7131 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7132 probe_rsp_ie_len[0], NULL,
7133 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7134 {
7135 hddLog(LOGE,
7136 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007137 ret = -EINVAL;
7138 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007139 }
7140 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
7141 }
7142
7143 if (probe_rsp_ie_len[1] > 0)
7144 {
7145 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7146 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
7147 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7148 probe_rsp_ie_len[1], NULL,
7149 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7150 {
7151 hddLog(LOGE,
7152 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007153 ret = -EINVAL;
7154 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007155 }
7156 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
7157 }
7158
7159 if (probe_rsp_ie_len[2] > 0)
7160 {
7161 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7162 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
7163 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7164 probe_rsp_ie_len[2], NULL,
7165 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7166 {
7167 hddLog(LOGE,
7168 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007169 ret = -EINVAL;
7170 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007171 }
7172 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
7173 }
7174
7175 if (probe_rsp_ie_len[1] == 0 )
7176 {
7177 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7178 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7179 eANI_BOOLEAN_FALSE) )
7180 {
7181 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007182 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007183 }
7184 }
7185
7186 if (probe_rsp_ie_len[2] == 0 )
7187 {
7188 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7189 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7190 eANI_BOOLEAN_FALSE) )
7191 {
7192 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007193 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007194 }
7195 }
7196
7197 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7198 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
7199 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7200 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7201 == eHAL_STATUS_FAILURE)
7202 {
7203 hddLog(LOGE,
7204 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007205 ret = -EINVAL;
7206 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007207 }
7208 }
7209 else
7210 {
7211 // Reset WNI_CFG_PROBE_RSP Flags
7212 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
7213
7214 hddLog(VOS_TRACE_LEVEL_INFO,
7215 "%s: No Probe Response IE received in set beacon",
7216 __func__);
7217 }
7218
7219 // Added for AssocResp IE
7220 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
7221 {
7222 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7223 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
7224 params->assocresp_ies_len, NULL,
7225 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7226 {
7227 hddLog(LOGE,
7228 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007229 ret = -EINVAL;
7230 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007231 }
7232
7233 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7234 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
7235 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7236 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7237 == eHAL_STATUS_FAILURE)
7238 {
7239 hddLog(LOGE,
7240 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007241 ret = -EINVAL;
7242 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007243 }
7244 }
7245 else
7246 {
7247 hddLog(VOS_TRACE_LEVEL_INFO,
7248 "%s: No Assoc Response IE received in set beacon",
7249 __func__);
7250
7251 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7252 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7253 eANI_BOOLEAN_FALSE) )
7254 {
7255 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007256 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007257 }
7258 }
7259
Jeff Johnsone7245742012-09-05 17:12:55 -07007260done:
Jeff Johnson295189b2012-06-20 16:38:30 -07007261 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307262 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007263}
Jeff Johnson295189b2012-06-20 16:38:30 -07007264
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307265/*
Jeff Johnson295189b2012-06-20 16:38:30 -07007266 * FUNCTION: wlan_hdd_validate_operation_channel
7267 * called by wlan_hdd_cfg80211_start_bss() and
7268 * wlan_hdd_cfg80211_set_channel()
7269 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307270 * channel list.
7271 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007272VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007273{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307274
Jeff Johnson295189b2012-06-20 16:38:30 -07007275 v_U32_t num_ch = 0;
7276 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7277 u32 indx = 0;
7278 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307279 v_U8_t fValidChannel = FALSE, count = 0;
7280 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307281
Jeff Johnson295189b2012-06-20 16:38:30 -07007282 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7283
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307284 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007285 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307286 /* Validate the channel */
7287 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007288 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307289 if ( channel == rfChannels[count].channelNum )
7290 {
7291 fValidChannel = TRUE;
7292 break;
7293 }
7294 }
7295 if (fValidChannel != TRUE)
7296 {
7297 hddLog(VOS_TRACE_LEVEL_ERROR,
7298 "%s: Invalid Channel [%d]", __func__, channel);
7299 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007300 }
7301 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307302 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007303 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307304 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7305 valid_ch, &num_ch))
7306 {
7307 hddLog(VOS_TRACE_LEVEL_ERROR,
7308 "%s: failed to get valid channel list", __func__);
7309 return VOS_STATUS_E_FAILURE;
7310 }
7311 for (indx = 0; indx < num_ch; indx++)
7312 {
7313 if (channel == valid_ch[indx])
7314 {
7315 break;
7316 }
7317 }
7318
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05307319 if (indx >= num_ch)
7320 {
7321 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
7322 {
7323 eCsrBand band;
7324 unsigned int freq;
7325
7326 sme_GetFreqBand(hHal, &band);
7327
7328 if (eCSR_BAND_5G == band)
7329 {
7330#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
7331 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
7332 {
7333 freq = ieee80211_channel_to_frequency(channel,
7334 IEEE80211_BAND_2GHZ);
7335 }
7336 else
7337 {
7338 freq = ieee80211_channel_to_frequency(channel,
7339 IEEE80211_BAND_5GHZ);
7340 }
7341#else
7342 freq = ieee80211_channel_to_frequency(channel);
7343#endif
7344 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
7345 return VOS_STATUS_SUCCESS;
7346 }
7347 }
7348
7349 hddLog(VOS_TRACE_LEVEL_ERROR,
7350 "%s: Invalid Channel [%d]", __func__, channel);
7351 return VOS_STATUS_E_FAILURE;
7352 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007353 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05307354
Jeff Johnson295189b2012-06-20 16:38:30 -07007355 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307356
Jeff Johnson295189b2012-06-20 16:38:30 -07007357}
7358
Viral Modi3a32cc52013-02-08 11:14:52 -08007359/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307360 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08007361 * This function is used to set the channel number
7362 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307363static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08007364 struct ieee80211_channel *chan,
7365 enum nl80211_channel_type channel_type
7366 )
7367{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307368 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08007369 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07007370 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08007371 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307372 hdd_context_t *pHddCtx;
7373 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007374
7375 ENTER();
7376
7377 if( NULL == dev )
7378 {
7379 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007380 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007381 return -ENODEV;
7382 }
7383 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307384
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307385 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7386 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
7387 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08007388 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307389 "%s: device_mode = %s (%d) freq = %d", __func__,
7390 hdd_device_modetoString(pAdapter->device_mode),
7391 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307392
7393 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7394 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307395 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08007396 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307397 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007398 }
7399
7400 /*
7401 * Do freq to chan conversion
7402 * TODO: for 11a
7403 */
7404
7405 channel = ieee80211_frequency_to_channel(freq);
7406
7407 /* Check freq range */
7408 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
7409 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
7410 {
7411 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007412 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08007413 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
7414 WNI_CFG_CURRENT_CHANNEL_STAMAX);
7415 return -EINVAL;
7416 }
7417
7418 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7419
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05307420 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
7421 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08007422 {
7423 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
7424 {
7425 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007426 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08007427 return -EINVAL;
7428 }
7429 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7430 "%s: set channel to [%d] for device mode =%d",
7431 __func__, channel,pAdapter->device_mode);
7432 }
7433 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08007434 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08007435 )
7436 {
7437 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7438 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
7439 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7440
7441 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
7442 {
7443 /* Link is up then return cant set channel*/
7444 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007445 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007446 return -EINVAL;
7447 }
7448
7449 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
7450 pHddStaCtx->conn_info.operationChannel = channel;
7451 pRoamProfile->ChannelInfo.ChannelList =
7452 &pHddStaCtx->conn_info.operationChannel;
7453 }
7454 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08007455 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08007456 )
7457 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307458 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
7459 {
7460 if(VOS_STATUS_SUCCESS !=
7461 wlan_hdd_validate_operation_channel(pAdapter,channel))
7462 {
7463 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007464 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307465 return -EINVAL;
7466 }
7467 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7468 }
7469 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08007470 {
7471 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
7472
7473 /* If auto channel selection is configured as enable/ 1 then ignore
7474 channel set by supplicant
7475 */
7476 if ( cfg_param->apAutoChannelSelection )
7477 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307478 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
7479 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08007480 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307481 "%s: set channel to auto channel (0) for device mode =%s (%d)",
7482 __func__, hdd_device_modetoString(pAdapter->device_mode),
7483 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08007484 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307485 else
7486 {
7487 if(VOS_STATUS_SUCCESS !=
7488 wlan_hdd_validate_operation_channel(pAdapter,channel))
7489 {
7490 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007491 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307492 return -EINVAL;
7493 }
7494 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7495 }
Viral Modi3a32cc52013-02-08 11:14:52 -08007496 }
7497 }
7498 else
7499 {
7500 hddLog(VOS_TRACE_LEVEL_FATAL,
7501 "%s: Invalid device mode failed to set valid channel", __func__);
7502 return -EINVAL;
7503 }
7504 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307505 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007506}
7507
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307508static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
7509 struct net_device *dev,
7510 struct ieee80211_channel *chan,
7511 enum nl80211_channel_type channel_type
7512 )
7513{
7514 int ret;
7515
7516 vos_ssr_protect(__func__);
7517 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
7518 vos_ssr_unprotect(__func__);
7519
7520 return ret;
7521}
7522
Jeff Johnson295189b2012-06-20 16:38:30 -07007523#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7524static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7525 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007526#else
7527static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7528 struct cfg80211_beacon_data *params,
7529 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307530 enum nl80211_hidden_ssid hidden_ssid,
7531 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007532#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007533{
7534 tsap_Config_t *pConfig;
7535 beacon_data_t *pBeacon = NULL;
7536 struct ieee80211_mgmt *pMgmt_frame;
7537 v_U8_t *pIe=NULL;
7538 v_U16_t capab_info;
7539 eCsrAuthType RSNAuthType;
7540 eCsrEncryptionType RSNEncryptType;
7541 eCsrEncryptionType mcRSNEncryptType;
7542 int status = VOS_STATUS_SUCCESS;
7543 tpWLAN_SAPEventCB pSapEventCallback;
7544 hdd_hostapd_state_t *pHostapdState;
7545 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
7546 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307547 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007548 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307549 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07007550 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08007551 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05307552 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07007553 v_BOOL_t MFPCapable = VOS_FALSE;
7554 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307555 v_BOOL_t sapEnable11AC =
7556 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07007557 ENTER();
7558
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307559 iniConfig = pHddCtx->cfg_ini;
7560
Jeff Johnson295189b2012-06-20 16:38:30 -07007561 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7562
7563 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7564
7565 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7566
7567 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7568
7569 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7570
7571 //channel is already set in the set_channel Call back
7572 //pConfig->channel = pCommitConfig->channel;
7573
7574 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307575 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07007576 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
7577
7578 pConfig->dtim_period = pBeacon->dtim_period;
7579
Arif Hussain6d2a3322013-11-17 19:50:10 -08007580 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07007581 pConfig->dtim_period);
7582
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08007583 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07007584 {
7585 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007586 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05307587 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
7588 {
7589 tANI_BOOLEAN restartNeeded;
7590 pConfig->ieee80211d = 1;
7591 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
7592 sme_setRegInfo(hHal, pConfig->countryCode);
7593 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
7594 }
7595 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007596 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07007597 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07007598 pConfig->ieee80211d = 1;
7599 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
7600 sme_setRegInfo(hHal, pConfig->countryCode);
7601 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07007602 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007603 else
7604 {
7605 pConfig->ieee80211d = 0;
7606 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307607 /*
7608 * If auto channel is configured i.e. channel is 0,
7609 * so skip channel validation.
7610 */
7611 if( AUTO_CHANNEL_SELECT != pConfig->channel )
7612 {
7613 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
7614 {
7615 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007616 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307617 return -EINVAL;
7618 }
7619 }
7620 else
7621 {
7622 if(1 != pHddCtx->is_dynamic_channel_range_set)
7623 {
7624 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
7625 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
7626 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
7627 }
7628 pHddCtx->is_dynamic_channel_range_set = 0;
7629 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007630 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007631 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007632 {
7633 pConfig->ieee80211d = 0;
7634 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307635
7636#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7637 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7638 pConfig->authType = eSAP_OPEN_SYSTEM;
7639 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7640 pConfig->authType = eSAP_SHARED_KEY;
7641 else
7642 pConfig->authType = eSAP_AUTO_SWITCH;
7643#else
7644 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7645 pConfig->authType = eSAP_OPEN_SYSTEM;
7646 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7647 pConfig->authType = eSAP_SHARED_KEY;
7648 else
7649 pConfig->authType = eSAP_AUTO_SWITCH;
7650#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007651
7652 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307653
7654 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07007655 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
7656
7657 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7658
7659 /*Set wps station to configured*/
7660 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7661
7662 if(pIe)
7663 {
7664 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
7665 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007666 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07007667 return -EINVAL;
7668 }
7669 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
7670 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007671 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07007672 /* Check 15 bit of WPS IE as it contain information for wps state
7673 * WPS state
7674 */
7675 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
7676 {
7677 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
7678 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
7679 {
7680 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7681 }
7682 }
7683 }
7684 else
7685 {
7686 pConfig->wps_state = SAP_WPS_DISABLED;
7687 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307688 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07007689
c_hpothufe599e92014-06-16 11:38:55 +05307690 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7691 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7692 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7693 eCSR_ENCRYPT_TYPE_NONE;
7694
Jeff Johnson295189b2012-06-20 16:38:30 -07007695 pConfig->RSNWPAReqIELength = 0;
7696 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307697 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007698 WLAN_EID_RSN);
7699 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307700 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007701 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7702 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7703 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307704 /* The actual processing may eventually be more extensive than
7705 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07007706 * by the app.
7707 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307708 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007709 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7710 &RSNEncryptType,
7711 &mcRSNEncryptType,
7712 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007713 &MFPCapable,
7714 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007715 pConfig->pRSNWPAReqIE[1]+2,
7716 pConfig->pRSNWPAReqIE );
7717
7718 if( VOS_STATUS_SUCCESS == status )
7719 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307720 /* Now copy over all the security attributes you have
7721 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007722 * */
7723 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7724 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7725 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7726 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307727 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007728 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007729 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7730 }
7731 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307732
Jeff Johnson295189b2012-06-20 16:38:30 -07007733 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7734 pBeacon->tail, pBeacon->tail_len);
7735
7736 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
7737 {
7738 if (pConfig->pRSNWPAReqIE)
7739 {
7740 /*Mixed mode WPA/WPA2*/
7741 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
7742 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7743 }
7744 else
7745 {
7746 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7747 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7748 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307749 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007750 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7751 &RSNEncryptType,
7752 &mcRSNEncryptType,
7753 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007754 &MFPCapable,
7755 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007756 pConfig->pRSNWPAReqIE[1]+2,
7757 pConfig->pRSNWPAReqIE );
7758
7759 if( VOS_STATUS_SUCCESS == status )
7760 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307761 /* Now copy over all the security attributes you have
7762 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007763 * */
7764 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7765 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7766 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7767 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307768 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007769 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007770 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7771 }
7772 }
7773 }
7774
Jeff Johnson4416a782013-03-25 14:17:50 -07007775 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
7776 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
7777 return -EINVAL;
7778 }
7779
Jeff Johnson295189b2012-06-20 16:38:30 -07007780 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
7781
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007782#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007783 if (params->ssid != NULL)
7784 {
7785 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
7786 pConfig->SSIDinfo.ssid.length = params->ssid_len;
7787 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7788 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7789 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007790#else
7791 if (ssid != NULL)
7792 {
7793 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
7794 pConfig->SSIDinfo.ssid.length = ssid_len;
7795 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7796 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7797 }
7798#endif
7799
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307800 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07007801 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307802
Jeff Johnson295189b2012-06-20 16:38:30 -07007803 /* default value */
7804 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7805 pConfig->num_accept_mac = 0;
7806 pConfig->num_deny_mac = 0;
7807
7808 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7809 pBeacon->tail, pBeacon->tail_len);
7810
7811 /* pIe for black list is following form:
7812 type : 1 byte
7813 length : 1 byte
7814 OUI : 4 bytes
7815 acl type : 1 byte
7816 no of mac addr in black list: 1 byte
7817 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307818 */
7819 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007820 {
7821 pConfig->SapMacaddr_acl = pIe[6];
7822 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007823 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007824 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307825 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7826 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007827 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7828 for (i = 0; i < pConfig->num_deny_mac; i++)
7829 {
7830 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7831 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307832 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007833 }
7834 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7835 pBeacon->tail, pBeacon->tail_len);
7836
7837 /* pIe for white list is following form:
7838 type : 1 byte
7839 length : 1 byte
7840 OUI : 4 bytes
7841 acl type : 1 byte
7842 no of mac addr in white list: 1 byte
7843 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307844 */
7845 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007846 {
7847 pConfig->SapMacaddr_acl = pIe[6];
7848 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007849 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007850 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307851 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7852 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007853 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7854 for (i = 0; i < pConfig->num_accept_mac; i++)
7855 {
7856 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7857 acl_entry++;
7858 }
7859 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307860
Jeff Johnson295189b2012-06-20 16:38:30 -07007861 wlan_hdd_set_sapHwmode(pHostapdAdapter);
7862
Jeff Johnsone7245742012-09-05 17:12:55 -07007863#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007864 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307865 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
7866 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05307867 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
7868 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007869 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
7870 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307871 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
7872 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07007873 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307874 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07007875 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307876 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007877
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307878 /* If ACS disable and selected channel <= 14
7879 * OR
7880 * ACS enabled and ACS operating band is choosen as 2.4
7881 * AND
7882 * VHT in 2.4G Disabled
7883 * THEN
7884 * Fallback to 11N mode
7885 */
7886 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
7887 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05307888 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307889 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007890 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307891 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
7892 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007893 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
7894 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007895 }
7896#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307897
Jeff Johnson295189b2012-06-20 16:38:30 -07007898 // ht_capab is not what the name conveys,this is used for protection bitmap
7899 pConfig->ht_capab =
7900 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
7901
7902 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
7903 {
7904 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7905 return -EINVAL;
7906 }
7907
7908 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307909 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07007910 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
7911 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307912 pConfig->obssProtEnabled =
7913 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07007914
Chet Lanctot8cecea22014-02-11 19:09:36 -08007915#ifdef WLAN_FEATURE_11W
7916 pConfig->mfpCapable = MFPCapable;
7917 pConfig->mfpRequired = MFPRequired;
7918 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
7919 pConfig->mfpCapable, pConfig->mfpRequired);
7920#endif
7921
Arif Hussain6d2a3322013-11-17 19:50:10 -08007922 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07007923 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007924 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
7925 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7926 (int)pConfig->channel);
7927 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
7928 pConfig->SapHw_mode, pConfig->privacy,
7929 pConfig->authType);
7930 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
7931 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7932 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7933 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07007934
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307935 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007936 {
7937 //Bss already started. just return.
7938 //TODO Probably it should update some beacon params.
7939 hddLog( LOGE, "Bss Already started...Ignore the request");
7940 EXIT();
7941 return 0;
7942 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307943
Agarwal Ashish51325b52014-06-16 16:50:49 +05307944 if (vos_max_concurrent_connections_reached()) {
7945 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7946 return -EINVAL;
7947 }
7948
Jeff Johnson295189b2012-06-20 16:38:30 -07007949 pConfig->persona = pHostapdAdapter->device_mode;
7950
Peng Xu2446a892014-09-05 17:21:18 +05307951 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
7952 if ( NULL != psmeConfig)
7953 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307954 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05307955 sme_GetConfigParam(hHal, psmeConfig);
7956 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307957#ifdef WLAN_FEATURE_AP_HT40_24G
7958 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7959 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
7960 && pHddCtx->cfg_ini->apHT40_24GEnabled)
7961 {
7962 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
7963 sme_UpdateConfig (hHal, psmeConfig);
7964 }
7965#endif
Peng Xu2446a892014-09-05 17:21:18 +05307966 vos_mem_free(psmeConfig);
7967 }
Peng Xuafc34e32014-09-25 13:23:55 +05307968 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05307969
Jeff Johnson295189b2012-06-20 16:38:30 -07007970 pSapEventCallback = hdd_hostapd_SAPEventCB;
7971 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
7972 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
7973 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007974 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007975 return -EINVAL;
7976 }
7977
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307978 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07007979 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7980
7981 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307982
Jeff Johnson295189b2012-06-20 16:38:30 -07007983 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307984 {
7985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007986 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07007987 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07007988 VOS_ASSERT(0);
7989 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307990
Jeff Johnson295189b2012-06-20 16:38:30 -07007991 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05307992 /* Initialize WMM configuation */
7993 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307994 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007995
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007996#ifdef WLAN_FEATURE_P2P_DEBUG
7997 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
7998 {
7999 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
8000 {
8001 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
8002 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08008003 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008004 }
8005 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
8006 {
8007 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
8008 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08008009 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008010 }
8011 }
8012#endif
8013
Jeff Johnson295189b2012-06-20 16:38:30 -07008014 pHostapdState->bCommit = TRUE;
8015 EXIT();
8016
8017 return 0;
8018}
8019
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008020#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308021static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308022 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008023 struct beacon_parameters *params)
8024{
8025 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308026 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308027 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008028
8029 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308030
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308031 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8032 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
8033 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308034 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
8035 hdd_device_modetoString(pAdapter->device_mode),
8036 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008037
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308038 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8039 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308040 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008041 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308042 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008043 }
8044
Agarwal Ashish51325b52014-06-16 16:50:49 +05308045 if (vos_max_concurrent_connections_reached()) {
8046 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8047 return -EINVAL;
8048 }
8049
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308050 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008051 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008052 )
8053 {
8054 beacon_data_t *old,*new;
8055
8056 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308057
Jeff Johnson295189b2012-06-20 16:38:30 -07008058 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308059 {
8060 hddLog(VOS_TRACE_LEVEL_WARN,
8061 FL("already beacon info added to session(%d)"),
8062 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008063 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308064 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008065
8066 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
8067
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308068 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07008069 {
8070 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008071 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008072 return -EINVAL;
8073 }
8074
8075 pAdapter->sessionCtx.ap.beacon = new;
8076
8077 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
8078 }
8079
8080 EXIT();
8081 return status;
8082}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308083
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308084static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
8085 struct net_device *dev,
8086 struct beacon_parameters *params)
8087{
8088 int ret;
8089
8090 vos_ssr_protect(__func__);
8091 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
8092 vos_ssr_unprotect(__func__);
8093
8094 return ret;
8095}
8096
8097static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008098 struct net_device *dev,
8099 struct beacon_parameters *params)
8100{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308101 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308102 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8103 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308104 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008105
8106 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308107
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308108 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8109 TRACE_CODE_HDD_CFG80211_SET_BEACON,
8110 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
8111 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8112 __func__, hdd_device_modetoString(pAdapter->device_mode),
8113 pAdapter->device_mode);
8114
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308115 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8116 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308117 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008118 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308119 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008120 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308121
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308122 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008123 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308124 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008125 {
8126 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308127
Jeff Johnson295189b2012-06-20 16:38:30 -07008128 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308129
Jeff Johnson295189b2012-06-20 16:38:30 -07008130 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308131 {
8132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8133 FL("session(%d) old and new heads points to NULL"),
8134 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008135 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308136 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008137
8138 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
8139
8140 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308141 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008142 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008143 return -EINVAL;
8144 }
8145
8146 pAdapter->sessionCtx.ap.beacon = new;
8147
8148 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
8149 }
8150
8151 EXIT();
8152 return status;
8153}
8154
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308155static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
8156 struct net_device *dev,
8157 struct beacon_parameters *params)
8158{
8159 int ret;
8160
8161 vos_ssr_protect(__func__);
8162 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
8163 vos_ssr_unprotect(__func__);
8164
8165 return ret;
8166}
8167
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008168#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8169
8170#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308171static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008172 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008173#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308174static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008175 struct net_device *dev)
8176#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008177{
8178 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07008179 hdd_context_t *pHddCtx = NULL;
8180 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308181 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308182 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008183
8184 ENTER();
8185
8186 if (NULL == pAdapter)
8187 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008189 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008190 return -ENODEV;
8191 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008192
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308193 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8194 TRACE_CODE_HDD_CFG80211_STOP_AP,
8195 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308196 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8197 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308198 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008199 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308200 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07008201 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008202
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008203 pScanInfo = &pHddCtx->scan_info;
8204
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308205 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8206 __func__, hdd_device_modetoString(pAdapter->device_mode),
8207 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008208
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308209 ret = wlan_hdd_scan_abort(pAdapter);
8210
Girish Gowli4bf7a632014-06-12 13:42:11 +05308211 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07008212 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8214 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308215
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308216 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07008217 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8219 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08008220
Jeff Johnsone7245742012-09-05 17:12:55 -07008221 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308222 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07008223 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308224 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008225 }
8226
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05308227 /* Delete all associated STAs before stopping AP/P2P GO */
8228 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05308229 hdd_hostapd_stop(dev);
8230
Jeff Johnson295189b2012-06-20 16:38:30 -07008231 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008232 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008233 )
8234 {
8235 beacon_data_t *old;
8236
8237 old = pAdapter->sessionCtx.ap.beacon;
8238
8239 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308240 {
8241 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8242 FL("session(%d) beacon data points to NULL"),
8243 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008244 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308245 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008246
Jeff Johnson295189b2012-06-20 16:38:30 -07008247 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008248
8249 mutex_lock(&pHddCtx->sap_lock);
8250 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8251 {
Jeff Johnson4416a782013-03-25 14:17:50 -07008252 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008253 {
8254 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8255
8256 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
8257
8258 if (!VOS_IS_STATUS_SUCCESS(status))
8259 {
8260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008261 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008262 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308263 }
8264 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008265 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05308266 /* BSS stopped, clear the active sessions for this device mode */
8267 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008268 }
8269 mutex_unlock(&pHddCtx->sap_lock);
8270
8271 if(status != VOS_STATUS_SUCCESS)
8272 {
8273 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008274 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008275 return -EINVAL;
8276 }
8277
Jeff Johnson4416a782013-03-25 14:17:50 -07008278 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008279 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
8280 ==eHAL_STATUS_FAILURE)
8281 {
8282 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008283 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008284 }
8285
Jeff Johnson4416a782013-03-25 14:17:50 -07008286 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008287 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8288 eANI_BOOLEAN_FALSE) )
8289 {
8290 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008291 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008292 }
8293
8294 // Reset WNI_CFG_PROBE_RSP Flags
8295 wlan_hdd_reset_prob_rspies(pAdapter);
8296
8297 pAdapter->sessionCtx.ap.beacon = NULL;
8298 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008299#ifdef WLAN_FEATURE_P2P_DEBUG
8300 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
8301 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
8302 {
8303 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
8304 "GO got removed");
8305 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
8306 }
8307#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008308 }
8309 EXIT();
8310 return status;
8311}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008312
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308313#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8314static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
8315 struct net_device *dev)
8316{
8317 int ret;
8318
8319 vos_ssr_protect(__func__);
8320 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
8321 vos_ssr_unprotect(__func__);
8322
8323 return ret;
8324}
8325#else
8326static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
8327 struct net_device *dev)
8328{
8329 int ret;
8330
8331 vos_ssr_protect(__func__);
8332 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
8333 vos_ssr_unprotect(__func__);
8334
8335 return ret;
8336}
8337#endif
8338
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008339#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
8340
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308341static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308342 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008343 struct cfg80211_ap_settings *params)
8344{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308345 hdd_adapter_t *pAdapter;
8346 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308347 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008348
8349 ENTER();
8350
Girish Gowlib143d7a2015-02-18 19:39:55 +05308351 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008352 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05308354 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308355 return -ENODEV;
8356 }
8357
8358 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8359 if (NULL == pAdapter)
8360 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308362 "%s: HDD adapter is Null", __func__);
8363 return -ENODEV;
8364 }
8365
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308366 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8367 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
8368 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308369 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8370 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308372 "%s: HDD adapter magic is invalid", __func__);
8373 return -ENODEV;
8374 }
8375
8376 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308377 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308378 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308379 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308380 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308381 }
8382
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308383 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
8384 __func__, hdd_device_modetoString(pAdapter->device_mode),
8385 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308386
8387 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008388 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008389 )
8390 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308391 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008392
8393 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308394
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008395 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308396 {
8397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8398 FL("already beacon info added to session(%d)"),
8399 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008400 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308401 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008402
Girish Gowlib143d7a2015-02-18 19:39:55 +05308403#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8404 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8405 &new,
8406 &params->beacon);
8407#else
8408 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8409 &new,
8410 &params->beacon,
8411 params->dtim_period);
8412#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008413
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308414 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008415 {
8416 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308417 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008418 return -EINVAL;
8419 }
8420 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08008421#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07008422 wlan_hdd_cfg80211_set_channel(wiphy, dev,
8423#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
8424 params->channel, params->channel_type);
8425#else
8426 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
8427#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08008428#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008429 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308430 params->ssid_len, params->hidden_ssid,
8431 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008432 }
8433
8434 EXIT();
8435 return status;
8436}
8437
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308438static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
8439 struct net_device *dev,
8440 struct cfg80211_ap_settings *params)
8441{
8442 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008443
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308444 vos_ssr_protect(__func__);
8445 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
8446 vos_ssr_unprotect(__func__);
8447
8448 return ret;
8449}
8450
8451static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008452 struct net_device *dev,
8453 struct cfg80211_beacon_data *params)
8454{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308455 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308456 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308457 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008458
8459 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308460
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308461 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8462 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
8463 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08008464 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008465 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308466
8467 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8468 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308469 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008470 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308471 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008472 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008473
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308474 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008475 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308476 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008477 {
8478 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308479
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008480 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308481
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008482 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308483 {
8484 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8485 FL("session(%d) beacon data points to NULL"),
8486 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008487 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308488 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008489
8490 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
8491
8492 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308493 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008494 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008495 return -EINVAL;
8496 }
8497
8498 pAdapter->sessionCtx.ap.beacon = new;
8499
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308500 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
8501 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008502 }
8503
8504 EXIT();
8505 return status;
8506}
8507
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308508static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8509 struct net_device *dev,
8510 struct cfg80211_beacon_data *params)
8511{
8512 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008513
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308514 vos_ssr_protect(__func__);
8515 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8516 vos_ssr_unprotect(__func__);
8517
8518 return ret;
8519}
8520
8521#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008522
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308523static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008524 struct net_device *dev,
8525 struct bss_parameters *params)
8526{
8527 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308528 hdd_context_t *pHddCtx;
8529 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008530
8531 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308532
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308533 if (NULL == pAdapter)
8534 {
8535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8536 "%s: HDD adapter is Null", __func__);
8537 return -ENODEV;
8538 }
8539 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308540 ret = wlan_hdd_validate_context(pHddCtx);
8541 if (0 != ret)
8542 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308543 return ret;
8544 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308545 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8546 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
8547 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308548 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8549 __func__, hdd_device_modetoString(pAdapter->device_mode),
8550 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008551
8552 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008553 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308554 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008555 {
8556 /* ap_isolate == -1 means that in change bss, upper layer doesn't
8557 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308558 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07008559 {
8560 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308561 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008562 }
8563
8564 EXIT();
8565 return 0;
8566}
8567
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308568static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
8569 struct net_device *dev,
8570 struct bss_parameters *params)
8571{
8572 int ret;
8573
8574 vos_ssr_protect(__func__);
8575 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
8576 vos_ssr_unprotect(__func__);
8577
8578 return ret;
8579}
Kiet Lam10841362013-11-01 11:36:50 +05308580/* FUNCTION: wlan_hdd_change_country_code_cd
8581* to wait for contry code completion
8582*/
8583void* wlan_hdd_change_country_code_cb(void *pAdapter)
8584{
8585 hdd_adapter_t *call_back_pAdapter = pAdapter;
8586 complete(&call_back_pAdapter->change_country_code);
8587 return NULL;
8588}
8589
Jeff Johnson295189b2012-06-20 16:38:30 -07008590/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308591 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07008592 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
8593 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308594int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008595 struct net_device *ndev,
8596 enum nl80211_iftype type,
8597 u32 *flags,
8598 struct vif_params *params
8599 )
8600{
8601 struct wireless_dev *wdev;
8602 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008603 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07008604 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008605 tCsrRoamProfile *pRoamProfile = NULL;
8606 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308607 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008608 eMib_dot11DesiredBssType connectedBssType;
8609 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308610 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008611
8612 ENTER();
8613
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308614 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008615 {
8616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8617 "%s: Adapter context is null", __func__);
8618 return VOS_STATUS_E_FAILURE;
8619 }
8620
8621 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8622 if (!pHddCtx)
8623 {
8624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8625 "%s: HDD context is null", __func__);
8626 return VOS_STATUS_E_FAILURE;
8627 }
8628
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308629 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8630 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
8631 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308632 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308633 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07008634 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308635 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008636 }
8637
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308638 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8639 __func__, hdd_device_modetoString(pAdapter->device_mode),
8640 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008641
Agarwal Ashish51325b52014-06-16 16:50:49 +05308642 if (vos_max_concurrent_connections_reached()) {
8643 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8644 return -EINVAL;
8645 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308646 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07008647 wdev = ndev->ieee80211_ptr;
8648
8649#ifdef WLAN_BTAMP_FEATURE
8650 if((NL80211_IFTYPE_P2P_CLIENT == type)||
8651 (NL80211_IFTYPE_ADHOC == type)||
8652 (NL80211_IFTYPE_AP == type)||
8653 (NL80211_IFTYPE_P2P_GO == type))
8654 {
8655 pHddCtx->isAmpAllowed = VOS_FALSE;
8656 // stop AMP traffic
8657 status = WLANBAP_StopAmp();
8658 if(VOS_STATUS_SUCCESS != status )
8659 {
8660 pHddCtx->isAmpAllowed = VOS_TRUE;
8661 hddLog(VOS_TRACE_LEVEL_FATAL,
8662 "%s: Failed to stop AMP", __func__);
8663 return -EINVAL;
8664 }
8665 }
8666#endif //WLAN_BTAMP_FEATURE
8667 /* Reset the current device mode bit mask*/
8668 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8669
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +05308670 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
8671 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
8672 (type == NL80211_IFTYPE_P2P_GO)))
8673 {
8674 /* Notify Mode change in case of concurrency.
8675 * Below function invokes TDLS teardown Functionality Since TDLS is
8676 * not Supported in case of concurrency i.e Once P2P session
8677 * is detected disable offchannel and teardown TDLS links
8678 */
8679 hddLog(LOG1,
8680 FL("Device mode = %d Interface type = %d"),
8681 pAdapter->device_mode, type);
8682 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
8683 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +05308684
Jeff Johnson295189b2012-06-20 16:38:30 -07008685 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008686 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07008687 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008688 )
8689 {
8690 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008691 if (!pWextState)
8692 {
8693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8694 "%s: pWextState is null", __func__);
8695 return VOS_STATUS_E_FAILURE;
8696 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008697 pRoamProfile = &pWextState->roamProfile;
8698 LastBSSType = pRoamProfile->BSSType;
8699
8700 switch (type)
8701 {
8702 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008703 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008704 hddLog(VOS_TRACE_LEVEL_INFO,
8705 "%s: setting interface Type to INFRASTRUCTURE", __func__);
8706 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008707#ifdef WLAN_FEATURE_11AC
8708 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
8709 {
8710 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
8711 }
8712#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308713 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07008714 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008715 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008716 //Check for sub-string p2p to confirm its a p2p interface
8717 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308718 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +05308719#ifdef FEATURE_WLAN_TDLS
8720 mutex_lock(&pHddCtx->tdls_lock);
8721 wlan_hdd_tdls_exit(pAdapter, TRUE);
8722 mutex_unlock(&pHddCtx->tdls_lock);
8723#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008724 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8725 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8726 }
8727 else
8728 {
8729 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008730 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008731 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008732 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05308733
Jeff Johnson295189b2012-06-20 16:38:30 -07008734 case NL80211_IFTYPE_ADHOC:
8735 hddLog(VOS_TRACE_LEVEL_INFO,
8736 "%s: setting interface Type to ADHOC", __func__);
8737 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
8738 pRoamProfile->phyMode =
8739 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07008740 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008741 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05308742 hdd_set_ibss_ops( pAdapter );
8743 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +05308744
8745 status = hdd_sta_id_hash_attach(pAdapter);
8746 if (VOS_STATUS_SUCCESS != status) {
8747 hddLog(VOS_TRACE_LEVEL_ERROR,
8748 FL("Failed to initialize hash for IBSS"));
8749 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008750 break;
8751
8752 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008753 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008754 {
8755 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8756 "%s: setting interface Type to %s", __func__,
8757 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
8758
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008759 //Cancel any remain on channel for GO mode
8760 if (NL80211_IFTYPE_P2P_GO == type)
8761 {
8762 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
8763 }
Mohit Khanna0f232092012-09-11 14:46:08 -07008764 if (NL80211_IFTYPE_AP == type)
8765 {
8766 /* As Loading WLAN Driver one interface being created for p2p device
8767 * address. This will take one HW STA and the max number of clients
8768 * that can connect to softAP will be reduced by one. so while changing
8769 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
8770 * interface as it is not required in SoftAP mode.
8771 */
8772
8773 // Get P2P Adapter
8774 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
8775
8776 if (pP2pAdapter)
8777 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308778 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05308779 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07008780 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
8781 }
8782 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05308783 //Disable IMPS & BMPS for SAP/GO
8784 if(VOS_STATUS_E_FAILURE ==
8785 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
8786 {
8787 //Fail to Exit BMPS
8788 VOS_ASSERT(0);
8789 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05308790
8791 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
8792
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308793#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07008794
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308795 /* A Mutex Lock is introduced while changing the mode to
8796 * protect the concurrent access for the Adapters by TDLS
8797 * module.
8798 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308799 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308800#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008801 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05308802 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008803 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07008804 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8805 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308806#ifdef FEATURE_WLAN_TDLS
8807 mutex_unlock(&pHddCtx->tdls_lock);
8808#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008809 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
8810 (pConfig->apRandomBssidEnabled))
8811 {
8812 /* To meet Android requirements create a randomized
8813 MAC address of the form 02:1A:11:Fx:xx:xx */
8814 get_random_bytes(&ndev->dev_addr[3], 3);
8815 ndev->dev_addr[0] = 0x02;
8816 ndev->dev_addr[1] = 0x1A;
8817 ndev->dev_addr[2] = 0x11;
8818 ndev->dev_addr[3] |= 0xF0;
8819 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
8820 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08008821 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
8822 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008823 }
8824
Jeff Johnson295189b2012-06-20 16:38:30 -07008825 hdd_set_ap_ops( pAdapter->dev );
8826
Kiet Lam10841362013-11-01 11:36:50 +05308827 /* This is for only SAP mode where users can
8828 * control country through ini.
8829 * P2P GO follows station country code
8830 * acquired during the STA scanning. */
8831 if((NL80211_IFTYPE_AP == type) &&
8832 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
8833 {
8834 int status = 0;
8835 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
8836 "%s: setting country code from INI ", __func__);
8837 init_completion(&pAdapter->change_country_code);
8838 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
8839 (void *)(tSmeChangeCountryCallback)
8840 wlan_hdd_change_country_code_cb,
8841 pConfig->apCntryCode, pAdapter,
8842 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308843 eSIR_FALSE,
8844 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05308845 if (eHAL_STATUS_SUCCESS == status)
8846 {
8847 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308848 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05308849 &pAdapter->change_country_code,
8850 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308851 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05308852 {
8853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308854 FL("SME Timed out while setting country code %ld"),
8855 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08008856
8857 if (pHddCtx->isLogpInProgress)
8858 {
8859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8860 "%s: LOGP in Progress. Ignore!!!", __func__);
8861 return -EAGAIN;
8862 }
Kiet Lam10841362013-11-01 11:36:50 +05308863 }
8864 }
8865 else
8866 {
8867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008868 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05308869 return -EINVAL;
8870 }
8871 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008872 status = hdd_init_ap_mode(pAdapter);
8873 if(status != VOS_STATUS_SUCCESS)
8874 {
8875 hddLog(VOS_TRACE_LEVEL_FATAL,
8876 "%s: Error initializing the ap mode", __func__);
8877 return -EINVAL;
8878 }
8879 hdd_set_conparam(1);
8880
Nirav Shah7e3c8132015-06-22 23:51:42 +05308881 status = hdd_sta_id_hash_attach(pAdapter);
8882 if (VOS_STATUS_SUCCESS != status)
8883 {
8884 hddLog(VOS_TRACE_LEVEL_ERROR,
8885 FL("Failed to initialize hash for AP"));
8886 return -EINVAL;
8887 }
8888
Jeff Johnson295189b2012-06-20 16:38:30 -07008889 /*interface type changed update in wiphy structure*/
8890 if(wdev)
8891 {
8892 wdev->iftype = type;
8893 pHddCtx->change_iface = type;
8894 }
8895 else
8896 {
8897 hddLog(VOS_TRACE_LEVEL_ERROR,
8898 "%s: ERROR !!!! Wireless dev is NULL", __func__);
8899 return -EINVAL;
8900 }
8901 goto done;
8902 }
8903
8904 default:
8905 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8906 __func__);
8907 return -EOPNOTSUPP;
8908 }
8909 }
8910 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008911 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008912 )
8913 {
8914 switch(type)
8915 {
8916 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008917 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008918 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05308919
8920 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308921#ifdef FEATURE_WLAN_TDLS
8922
8923 /* A Mutex Lock is introduced while changing the mode to
8924 * protect the concurrent access for the Adapters by TDLS
8925 * module.
8926 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308927 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308928#endif
c_hpothu002231a2015-02-05 14:58:51 +05308929 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008930 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008931 //Check for sub-string p2p to confirm its a p2p interface
8932 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008933 {
8934 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8935 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8936 }
8937 else
8938 {
8939 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008940 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008941 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008942 hdd_set_conparam(0);
8943 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008944 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
8945 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308946#ifdef FEATURE_WLAN_TDLS
8947 mutex_unlock(&pHddCtx->tdls_lock);
8948#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308949 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008950 if( VOS_STATUS_SUCCESS != status )
8951 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07008952 /* In case of JB, for P2P-GO, only change interface will be called,
8953 * This is the right place to enable back bmps_imps()
8954 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308955 if (pHddCtx->hdd_wlan_suspended)
8956 {
8957 hdd_set_pwrparams(pHddCtx);
8958 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008959 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008960 goto done;
8961 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008962 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008963 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008964 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8965 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008966 goto done;
8967 default:
8968 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8969 __func__);
8970 return -EOPNOTSUPP;
8971
8972 }
8973
8974 }
8975 else
8976 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308977 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
8978 __func__, hdd_device_modetoString(pAdapter->device_mode),
8979 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008980 return -EOPNOTSUPP;
8981 }
8982
8983
8984 if(pRoamProfile)
8985 {
8986 if ( LastBSSType != pRoamProfile->BSSType )
8987 {
8988 /*interface type changed update in wiphy structure*/
8989 wdev->iftype = type;
8990
8991 /*the BSS mode changed, We need to issue disconnect
8992 if connected or in IBSS disconnect state*/
8993 if ( hdd_connGetConnectedBssType(
8994 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
8995 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
8996 {
8997 /*need to issue a disconnect to CSR.*/
8998 INIT_COMPLETION(pAdapter->disconnect_comp_var);
8999 if( eHAL_STATUS_SUCCESS ==
9000 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
9001 pAdapter->sessionId,
9002 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
9003 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309004 ret = wait_for_completion_interruptible_timeout(
9005 &pAdapter->disconnect_comp_var,
9006 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
9007 if (ret <= 0)
9008 {
9009 hddLog(VOS_TRACE_LEVEL_ERROR,
9010 FL("wait on disconnect_comp_var failed %ld"), ret);
9011 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009012 }
9013 }
9014 }
9015 }
9016
9017done:
9018 /*set bitmask based on updated value*/
9019 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07009020
9021 /* Only STA mode support TM now
9022 * all other mode, TM feature should be disabled */
9023 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
9024 (~VOS_STA & pHddCtx->concurrency_mode) )
9025 {
9026 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
9027 }
9028
Jeff Johnson295189b2012-06-20 16:38:30 -07009029#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309030 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05309031 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07009032 {
9033 //we are ok to do AMP
9034 pHddCtx->isAmpAllowed = VOS_TRUE;
9035 }
9036#endif //WLAN_BTAMP_FEATURE
9037 EXIT();
9038 return 0;
9039}
9040
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05309041/*
9042 * FUNCTION: wlan_hdd_cfg80211_change_iface
9043 * wrapper function to protect the actual implementation from SSR.
9044 */
9045int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
9046 struct net_device *ndev,
9047 enum nl80211_iftype type,
9048 u32 *flags,
9049 struct vif_params *params
9050 )
9051{
9052 int ret;
9053
9054 vos_ssr_protect(__func__);
9055 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
9056 vos_ssr_unprotect(__func__);
9057
9058 return ret;
9059}
9060
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009061#ifdef FEATURE_WLAN_TDLS
9062static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309063 struct net_device *dev,
9064#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9065 const u8 *mac,
9066#else
9067 u8 *mac,
9068#endif
9069 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009070{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009071 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009072 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309073 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309074 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05309075 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309076 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009077
9078 ENTER();
9079
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05309080 if (!dev) {
9081 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
9082 return -EINVAL;
9083 }
9084
9085 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9086 if (!pAdapter) {
9087 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
9088 return -EINVAL;
9089 }
9090
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309091 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009092 {
9093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9094 "Invalid arguments");
9095 return -EINVAL;
9096 }
Hoonki Lee27511902013-03-14 18:19:06 -07009097
9098 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
9099 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
9100 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309101 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07009102 "%s: TDLS mode is disabled OR not enabled in FW."
9103 MAC_ADDRESS_STR " Request declined.",
9104 __func__, MAC_ADDR_ARRAY(mac));
9105 return -ENOTSUPP;
9106 }
9107
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009108 if (pHddCtx->isLogpInProgress)
9109 {
9110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9111 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05309112 wlan_hdd_tdls_set_link_status(pAdapter,
9113 mac,
9114 eTDLS_LINK_IDLE,
9115 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009116 return -EBUSY;
9117 }
9118
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309119 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05309120 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009121
9122 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009124 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
9125 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309126 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009127 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009128 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309129 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009130
9131 /* in add station, we accept existing valid staId if there is */
9132 if ((0 == update) &&
9133 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
9134 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009135 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309136 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009137 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009138 " link_status %d. staId %d. add station ignored.",
9139 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
9140 return 0;
9141 }
9142 /* in change station, we accept only when staId is valid */
9143 if ((1 == update) &&
9144 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
9145 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
9146 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009148 "%s: " MAC_ADDRESS_STR
9149 " link status %d. staId %d. change station %s.",
9150 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
9151 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
9152 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009153 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009154
9155 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05309156 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009157 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9159 "%s: " MAC_ADDRESS_STR
9160 " TDLS setup is ongoing. Request declined.",
9161 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07009162 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009163 }
9164
9165 /* first to check if we reached to maximum supported TDLS peer.
9166 TODO: for now, return -EPERM looks working fine,
9167 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309168 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
9169 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009170 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9172 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309173 " TDLS Max peer already connected. Request declined."
9174 " Num of peers (%d), Max allowed (%d).",
9175 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
9176 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009177 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009178 }
9179 else
9180 {
9181 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309182 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009183 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009184 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009185 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9186 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
9187 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009188 return -EPERM;
9189 }
9190 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009191 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05309192 wlan_hdd_tdls_set_link_status(pAdapter,
9193 mac,
9194 eTDLS_LINK_CONNECTING,
9195 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009196
Jeff Johnsond75fe012013-04-06 10:53:06 -07009197 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309198 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009199 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009201 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009202 if(StaParams->htcap_present)
9203 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009205 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009207 "ht_capa->extended_capabilities: %0x",
9208 StaParams->HTCap.extendedHtCapInfo);
9209 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009211 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009213 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009214 if(StaParams->vhtcap_present)
9215 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009217 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
9218 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
9219 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
9220 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009221 {
9222 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009224 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309225 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009226 "[%d]: %x ", i, StaParams->supported_rates[i]);
9227 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07009228 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309229 else if ((1 == update) && (NULL == StaParams))
9230 {
9231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9232 "%s : update is true, but staParams is NULL. Error!", __func__);
9233 return -EPERM;
9234 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009235
9236 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
9237
9238 if (!update)
9239 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309240 /*Before adding sta make sure that device exited from BMPS*/
9241 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
9242 {
9243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9244 "%s: Adding tdls peer sta. Disable BMPS", __func__);
9245 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
9246 if (status != VOS_STATUS_SUCCESS) {
9247 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
9248 }
9249 }
9250
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309251 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009252 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309253 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309254 hddLog(VOS_TRACE_LEVEL_ERROR,
9255 FL("Failed to add TDLS peer STA. Enable Bmps"));
9256 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309257 return -EPERM;
9258 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009259 }
9260 else
9261 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309262 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009263 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309264 if (ret != eHAL_STATUS_SUCCESS) {
9265 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
9266 return -EPERM;
9267 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009268 }
9269
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309270 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009271 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
9272
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309273 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009274 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009275 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309276 "%s: timeout waiting for tdls add station indication %ld",
9277 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009278 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009279 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309280
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009281 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
9282 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009284 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009285 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009286 }
9287
9288 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07009289
9290error:
Atul Mittal115287b2014-07-08 13:26:33 +05309291 wlan_hdd_tdls_set_link_status(pAdapter,
9292 mac,
9293 eTDLS_LINK_IDLE,
9294 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009295 return -EPERM;
9296
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009297}
9298#endif
9299
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309300static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009301 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309302#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9303 const u8 *mac,
9304#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009305 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309306#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009307 struct station_parameters *params)
9308{
9309 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309310 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309311 hdd_context_t *pHddCtx;
9312 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009313 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309314 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009315#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009316 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009317 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309318 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009319#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009320
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309321 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309322
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309323 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05309324 if ((NULL == pAdapter))
9325 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309327 "invalid adapter ");
9328 return -EINVAL;
9329 }
9330
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309331 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9332 TRACE_CODE_HDD_CHANGE_STATION,
9333 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05309334 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05309335
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309336 ret = wlan_hdd_validate_context(pHddCtx);
9337 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05309338 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309339 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309340 }
9341
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309342 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9343
9344 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009345 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9347 "invalid HDD station context");
9348 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009349 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009350 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
9351
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009352 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
9353 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07009354 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009355 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07009356 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309357 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07009358 WLANTL_STA_AUTHENTICATED);
9359
Gopichand Nakkala29149562013-05-10 21:43:41 +05309360 if (status != VOS_STATUS_SUCCESS)
9361 {
9362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9363 "%s: Not able to change TL state to AUTHENTICATED", __func__);
9364 return -EINVAL;
9365 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009366 }
9367 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07009368 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9369 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309370#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009371 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
9372 StaParams.capability = params->capability;
9373 StaParams.uapsd_queues = params->uapsd_queues;
9374 StaParams.max_sp = params->max_sp;
9375
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309376 /* Convert (first channel , number of channels) tuple to
9377 * the total list of channels. This goes with the assumption
9378 * that if the first channel is < 14, then the next channels
9379 * are an incremental of 1 else an incremental of 4 till the number
9380 * of channels.
9381 */
9382 if (0 != params->supported_channels_len) {
9383 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
9384 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
9385 {
9386 int wifi_chan_index;
9387 StaParams.supported_channels[j] = params->supported_channels[i];
9388 wifi_chan_index =
9389 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
9390 no_of_channels = params->supported_channels[i+1];
9391 for(k=1; k <= no_of_channels; k++)
9392 {
9393 StaParams.supported_channels[j+1] =
9394 StaParams.supported_channels[j] + wifi_chan_index;
9395 j+=1;
9396 }
9397 }
9398 StaParams.supported_channels_len = j;
9399 }
9400 vos_mem_copy(StaParams.supported_oper_classes,
9401 params->supported_oper_classes,
9402 params->supported_oper_classes_len);
9403 StaParams.supported_oper_classes_len =
9404 params->supported_oper_classes_len;
9405
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009406 if (0 != params->ext_capab_len)
9407 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
9408 sizeof(StaParams.extn_capability));
9409
9410 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009411 {
9412 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009413 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009414 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009415
9416 StaParams.supported_rates_len = params->supported_rates_len;
9417
9418 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
9419 * The supported_rates array , for all the structures propogating till Add Sta
9420 * to the firmware has to be modified , if the supplicant (ieee80211) is
9421 * modified to send more rates.
9422 */
9423
9424 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
9425 */
9426 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
9427 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
9428
9429 if (0 != StaParams.supported_rates_len) {
9430 int i = 0;
9431 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
9432 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009433 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009434 "Supported Rates with Length %d", StaParams.supported_rates_len);
9435 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009437 "[%d]: %0x", i, StaParams.supported_rates[i]);
9438 }
9439
9440 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009441 {
9442 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009443 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009444 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009445
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009446 if (0 != params->ext_capab_len ) {
9447 /*Define A Macro : TODO Sunil*/
9448 if ((1<<4) & StaParams.extn_capability[3]) {
9449 isBufSta = 1;
9450 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309451 /* TDLS Channel Switching Support */
9452 if ((1<<6) & StaParams.extn_capability[3]) {
9453 isOffChannelSupported = 1;
9454 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009455 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309456 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
9457 &StaParams, isBufSta,
9458 isOffChannelSupported);
9459
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309460 if (VOS_STATUS_SUCCESS != status) {
9461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9462 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
9463 return -EINVAL;
9464 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009465 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
9466
9467 if (VOS_STATUS_SUCCESS != status) {
9468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9469 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
9470 return -EINVAL;
9471 }
9472 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009473#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05309474 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009475 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009476 return status;
9477}
9478
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309479#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
9480static int wlan_hdd_change_station(struct wiphy *wiphy,
9481 struct net_device *dev,
9482 const u8 *mac,
9483 struct station_parameters *params)
9484#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309485static int wlan_hdd_change_station(struct wiphy *wiphy,
9486 struct net_device *dev,
9487 u8 *mac,
9488 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309489#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309490{
9491 int ret;
9492
9493 vos_ssr_protect(__func__);
9494 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
9495 vos_ssr_unprotect(__func__);
9496
9497 return ret;
9498}
9499
Jeff Johnson295189b2012-06-20 16:38:30 -07009500/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309501 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009502 * This function is used to initialize the key information
9503 */
9504#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309505static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009506 struct net_device *ndev,
9507 u8 key_index, bool pairwise,
9508 const u8 *mac_addr,
9509 struct key_params *params
9510 )
9511#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309512static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009513 struct net_device *ndev,
9514 u8 key_index, const u8 *mac_addr,
9515 struct key_params *params
9516 )
9517#endif
9518{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009519 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07009520 tCsrRoamSetKey setKey;
9521 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309522 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009523 v_U32_t roamId= 0xFF;
9524 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009525 hdd_hostapd_state_t *pHostapdState;
9526 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009527 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309528 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009529
9530 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309531
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309532 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9533 TRACE_CODE_HDD_CFG80211_ADD_KEY,
9534 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309535 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9536 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309537 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009538 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309539 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009540 }
9541
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309542 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9543 __func__, hdd_device_modetoString(pAdapter->device_mode),
9544 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009545
9546 if (CSR_MAX_NUM_KEY <= key_index)
9547 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009548 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009549 key_index);
9550
9551 return -EINVAL;
9552 }
9553
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009554 if (CSR_MAX_KEY_LEN < params->key_len)
9555 {
9556 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
9557 params->key_len);
9558
9559 return -EINVAL;
9560 }
9561
9562 hddLog(VOS_TRACE_LEVEL_INFO,
9563 "%s: called with key index = %d & key length %d",
9564 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009565
9566 /*extract key idx, key len and key*/
9567 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9568 setKey.keyId = key_index;
9569 setKey.keyLength = params->key_len;
9570 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
9571
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009572 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009573 {
9574 case WLAN_CIPHER_SUITE_WEP40:
9575 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
9576 break;
9577
9578 case WLAN_CIPHER_SUITE_WEP104:
9579 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
9580 break;
9581
9582 case WLAN_CIPHER_SUITE_TKIP:
9583 {
9584 u8 *pKey = &setKey.Key[0];
9585 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
9586
9587 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
9588
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009589 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07009590
9591 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009592 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009593 |--------------|----------|----------|
9594 <---16bytes---><--8bytes--><--8bytes-->
9595
9596 */
9597 /*Sme expects the 32 bytes key to be in the below order
9598
9599 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009600 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009601 |--------------|----------|----------|
9602 <---16bytes---><--8bytes--><--8bytes-->
9603 */
9604 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009605 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07009606
9607 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009608 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009609
9610 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009611 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009612
9613
9614 break;
9615 }
9616
9617 case WLAN_CIPHER_SUITE_CCMP:
9618 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
9619 break;
9620
9621#ifdef FEATURE_WLAN_WAPI
9622 case WLAN_CIPHER_SUITE_SMS4:
9623 {
9624 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9625 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
9626 params->key, params->key_len);
9627 return 0;
9628 }
9629#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009630
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009631#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009632 case WLAN_CIPHER_SUITE_KRK:
9633 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
9634 break;
9635#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009636
9637#ifdef WLAN_FEATURE_11W
9638 case WLAN_CIPHER_SUITE_AES_CMAC:
9639 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07009640 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07009641#endif
9642
Jeff Johnson295189b2012-06-20 16:38:30 -07009643 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009644 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009645 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309646 status = -EOPNOTSUPP;
9647 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009648 }
9649
9650 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
9651 __func__, setKey.encType);
9652
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009653 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07009654#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9655 (!pairwise)
9656#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009657 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07009658#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009659 )
9660 {
9661 /* set group key*/
9662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9663 "%s- %d: setting Broadcast key",
9664 __func__, __LINE__);
9665 setKey.keyDirection = eSIR_RX_ONLY;
9666 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9667 }
9668 else
9669 {
9670 /* set pairwise key*/
9671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9672 "%s- %d: setting pairwise key",
9673 __func__, __LINE__);
9674 setKey.keyDirection = eSIR_TX_RX;
9675 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9676 }
9677 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
9678 {
9679 setKey.keyDirection = eSIR_TX_RX;
9680 /*Set the group key*/
9681 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9682 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07009683
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009684 if ( 0 != status )
9685 {
9686 hddLog(VOS_TRACE_LEVEL_ERROR,
9687 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309688 status = -EINVAL;
9689 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009690 }
9691 /*Save the keys here and call sme_RoamSetKey for setting
9692 the PTK after peer joins the IBSS network*/
9693 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
9694 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309695 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009696 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05309697 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
9698 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
9699 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009700 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009701 if( pHostapdState->bssState == BSS_START )
9702 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009703 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9704 vos_status = wlan_hdd_check_ula_done(pAdapter);
9705
9706 if ( vos_status != VOS_STATUS_SUCCESS )
9707 {
9708 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9709 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9710 __LINE__, vos_status );
9711
9712 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9713
9714 status = -EINVAL;
9715 goto end;
9716 }
9717
Jeff Johnson295189b2012-06-20 16:38:30 -07009718 status = WLANSAP_SetKeySta( pVosContext, &setKey);
9719
9720 if ( status != eHAL_STATUS_SUCCESS )
9721 {
9722 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9723 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9724 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309725 status = -EINVAL;
9726 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009727 }
9728 }
9729
9730 /* Saving WEP keys */
9731 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
9732 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
9733 {
9734 //Save the wep key in ap context. Issue setkey after the BSS is started.
9735 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9736 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
9737 }
9738 else
9739 {
9740 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009741 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009742 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
9743 }
9744 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009745 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
9746 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009747 {
9748 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9749 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9750
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309751#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9752 if (!pairwise)
9753#else
9754 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9755#endif
9756 {
9757 /* set group key*/
9758 if (pHddStaCtx->roam_info.deferKeyComplete)
9759 {
9760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9761 "%s- %d: Perform Set key Complete",
9762 __func__, __LINE__);
9763 hdd_PerformRoamSetKeyComplete(pAdapter);
9764 }
9765 }
9766
Jeff Johnson295189b2012-06-20 16:38:30 -07009767 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
9768
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08009769 pWextState->roamProfile.Keys.defaultIndex = key_index;
9770
9771
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009772 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009773 params->key, params->key_len);
9774
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309775
Jeff Johnson295189b2012-06-20 16:38:30 -07009776 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9777
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309778 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009779 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309780 __func__, setKey.peerMac[0], setKey.peerMac[1],
9781 setKey.peerMac[2], setKey.peerMac[3],
9782 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009783 setKey.keyDirection);
9784
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009785 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +05309786
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009787 if ( vos_status != VOS_STATUS_SUCCESS )
9788 {
9789 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009790 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9791 __LINE__, vos_status );
9792
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009793 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009794
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009795 status = -EINVAL;
9796 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009797
9798 }
9799
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009800#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309801 /* The supplicant may attempt to set the PTK once pre-authentication
9802 is done. Save the key in the UMAC and include it in the ADD BSS
9803 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009804 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309805 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009806 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309807 hddLog(VOS_TRACE_LEVEL_INFO_MED,
9808 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309809 status = 0;
9810 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309811 }
9812 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
9813 {
9814 hddLog(VOS_TRACE_LEVEL_ERROR,
9815 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309816 status = -EINVAL;
9817 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009818 }
9819#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07009820
9821 /* issue set key request to SME*/
9822 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9823 pAdapter->sessionId, &setKey, &roamId );
9824
9825 if ( 0 != status )
9826 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309827 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009828 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
9829 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309830 status = -EINVAL;
9831 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009832 }
9833
9834
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309835 /* in case of IBSS as there was no information available about WEP keys during
9836 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07009837 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309838 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
9839 !( ( IW_AUTH_KEY_MGMT_802_1X
9840 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07009841 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
9842 )
9843 &&
9844 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
9845 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
9846 )
9847 )
9848 {
9849 setKey.keyDirection = eSIR_RX_ONLY;
9850 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9851
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309852 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009853 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309854 __func__, setKey.peerMac[0], setKey.peerMac[1],
9855 setKey.peerMac[2], setKey.peerMac[3],
9856 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009857 setKey.keyDirection);
9858
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309859 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009860 pAdapter->sessionId, &setKey, &roamId );
9861
9862 if ( 0 != status )
9863 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309864 hddLog(VOS_TRACE_LEVEL_ERROR,
9865 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009866 __func__, status);
9867 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309868 status = -EINVAL;
9869 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009870 }
9871 }
9872 }
9873
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309874end:
9875 /* Need to clear any trace of key value in the memory.
9876 * Thus zero out the memory even though it is local
9877 * variable.
9878 */
9879 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309880 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309881 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009882}
9883
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309884#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9885static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9886 struct net_device *ndev,
9887 u8 key_index, bool pairwise,
9888 const u8 *mac_addr,
9889 struct key_params *params
9890 )
9891#else
9892static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9893 struct net_device *ndev,
9894 u8 key_index, const u8 *mac_addr,
9895 struct key_params *params
9896 )
9897#endif
9898{
9899 int ret;
9900 vos_ssr_protect(__func__);
9901#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9902 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
9903 mac_addr, params);
9904#else
9905 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
9906 params);
9907#endif
9908 vos_ssr_unprotect(__func__);
9909
9910 return ret;
9911}
9912
Jeff Johnson295189b2012-06-20 16:38:30 -07009913/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309914 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009915 * This function is used to get the key information
9916 */
9917#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309918static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309919 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009920 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309921 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009922 const u8 *mac_addr, void *cookie,
9923 void (*callback)(void *cookie, struct key_params*)
9924 )
9925#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309926static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309927 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009928 struct net_device *ndev,
9929 u8 key_index, const u8 *mac_addr, void *cookie,
9930 void (*callback)(void *cookie, struct key_params*)
9931 )
9932#endif
9933{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309934 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309935 hdd_wext_state_t *pWextState = NULL;
9936 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009937 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309938 hdd_context_t *pHddCtx;
9939 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009940
9941 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309942
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309943 if (NULL == pAdapter)
9944 {
9945 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9946 "%s: HDD adapter is Null", __func__);
9947 return -ENODEV;
9948 }
9949
9950 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9951 ret = wlan_hdd_validate_context(pHddCtx);
9952 if (0 != ret)
9953 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309954 return ret;
9955 }
9956
9957 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9958 pRoamProfile = &(pWextState->roamProfile);
9959
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309960 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9961 __func__, hdd_device_modetoString(pAdapter->device_mode),
9962 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309963
Jeff Johnson295189b2012-06-20 16:38:30 -07009964 memset(&params, 0, sizeof(params));
9965
9966 if (CSR_MAX_NUM_KEY <= key_index)
9967 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309968 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07009969 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309970 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009971
9972 switch(pRoamProfile->EncryptionType.encryptionType[0])
9973 {
9974 case eCSR_ENCRYPT_TYPE_NONE:
9975 params.cipher = IW_AUTH_CIPHER_NONE;
9976 break;
9977
9978 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
9979 case eCSR_ENCRYPT_TYPE_WEP40:
9980 params.cipher = WLAN_CIPHER_SUITE_WEP40;
9981 break;
9982
9983 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
9984 case eCSR_ENCRYPT_TYPE_WEP104:
9985 params.cipher = WLAN_CIPHER_SUITE_WEP104;
9986 break;
9987
9988 case eCSR_ENCRYPT_TYPE_TKIP:
9989 params.cipher = WLAN_CIPHER_SUITE_TKIP;
9990 break;
9991
9992 case eCSR_ENCRYPT_TYPE_AES:
9993 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
9994 break;
9995
9996 default:
9997 params.cipher = IW_AUTH_CIPHER_NONE;
9998 break;
9999 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010000
c_hpothuaaf19692014-05-17 17:01:48 +053010001 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10002 TRACE_CODE_HDD_CFG80211_GET_KEY,
10003 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010004
Jeff Johnson295189b2012-06-20 16:38:30 -070010005 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
10006 params.seq_len = 0;
10007 params.seq = NULL;
10008 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
10009 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010010 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010011 return 0;
10012}
10013
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010014#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10015static int wlan_hdd_cfg80211_get_key(
10016 struct wiphy *wiphy,
10017 struct net_device *ndev,
10018 u8 key_index, bool pairwise,
10019 const u8 *mac_addr, void *cookie,
10020 void (*callback)(void *cookie, struct key_params*)
10021 )
10022#else
10023static int wlan_hdd_cfg80211_get_key(
10024 struct wiphy *wiphy,
10025 struct net_device *ndev,
10026 u8 key_index, const u8 *mac_addr, void *cookie,
10027 void (*callback)(void *cookie, struct key_params*)
10028 )
10029#endif
10030{
10031 int ret;
10032
10033 vos_ssr_protect(__func__);
10034#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10035 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
10036 mac_addr, cookie, callback);
10037#else
10038 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
10039 callback);
10040#endif
10041 vos_ssr_unprotect(__func__);
10042
10043 return ret;
10044}
10045
Jeff Johnson295189b2012-06-20 16:38:30 -070010046/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010047 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 * This function is used to delete the key information
10049 */
10050#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010051static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010052 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010053 u8 key_index,
10054 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070010055 const u8 *mac_addr
10056 )
10057#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010058static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010059 struct net_device *ndev,
10060 u8 key_index,
10061 const u8 *mac_addr
10062 )
10063#endif
10064{
10065 int status = 0;
10066
10067 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010068 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070010069 //it is observed that this is invalidating peer
10070 //key index whenever re-key is done. This is affecting data link.
10071 //It should be ok to ignore del_key.
10072#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010073 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
10074 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010075 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
10076 tCsrRoamSetKey setKey;
10077 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010078
Jeff Johnson295189b2012-06-20 16:38:30 -070010079 ENTER();
10080
10081 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
10082 __func__,pAdapter->device_mode);
10083
10084 if (CSR_MAX_NUM_KEY <= key_index)
10085 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010086 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010087 key_index);
10088
10089 return -EINVAL;
10090 }
10091
10092 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10093 setKey.keyId = key_index;
10094
10095 if (mac_addr)
10096 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
10097 else
10098 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
10099
10100 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
10101
10102 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010103 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010104 )
10105 {
10106
10107 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070010108 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10109 if( pHostapdState->bssState == BSS_START)
10110 {
10111 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010112
Jeff Johnson295189b2012-06-20 16:38:30 -070010113 if ( status != eHAL_STATUS_SUCCESS )
10114 {
10115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10116 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
10117 __LINE__, status );
10118 }
10119 }
10120 }
10121 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010122 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070010123 )
10124 {
10125 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10126
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010127 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
10128
10129 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070010130 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010131 __func__, setKey.peerMac[0], setKey.peerMac[1],
10132 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070010133 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010134 if(pAdapter->sessionCtx.station.conn_info.connState ==
10135 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070010136 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010137 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010138 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010139
Jeff Johnson295189b2012-06-20 16:38:30 -070010140 if ( 0 != status )
10141 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010142 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010143 "%s: sme_RoamSetKey failure, returned %d",
10144 __func__, status);
10145 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
10146 return -EINVAL;
10147 }
10148 }
10149 }
10150#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010151 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010152 return status;
10153}
10154
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010155#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10156static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10157 struct net_device *ndev,
10158 u8 key_index,
10159 bool pairwise,
10160 const u8 *mac_addr
10161 )
10162#else
10163static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10164 struct net_device *ndev,
10165 u8 key_index,
10166 const u8 *mac_addr
10167 )
10168#endif
10169{
10170 int ret;
10171
10172 vos_ssr_protect(__func__);
10173#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10174 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
10175 mac_addr);
10176#else
10177 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
10178#endif
10179 vos_ssr_unprotect(__func__);
10180
10181 return ret;
10182}
10183
Jeff Johnson295189b2012-06-20 16:38:30 -070010184/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010185 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010186 * This function is used to set the default tx key index
10187 */
10188#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010189static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010190 struct net_device *ndev,
10191 u8 key_index,
10192 bool unicast, bool multicast)
10193#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010194static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010195 struct net_device *ndev,
10196 u8 key_index)
10197#endif
10198{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010199 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010200 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010201 hdd_wext_state_t *pWextState;
10202 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010203 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010204
10205 ENTER();
10206
Gopichand Nakkala29149562013-05-10 21:43:41 +053010207 if ((NULL == pAdapter))
10208 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010210 "invalid adapter");
10211 return -EINVAL;
10212 }
10213
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010214 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10215 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
10216 pAdapter->sessionId, key_index));
10217
Gopichand Nakkala29149562013-05-10 21:43:41 +053010218 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10219 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10220
10221 if ((NULL == pWextState) || (NULL == pHddStaCtx))
10222 {
10223 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10224 "invalid Wext state or HDD context");
10225 return -EINVAL;
10226 }
10227
Arif Hussain6d2a3322013-11-17 19:50:10 -080010228 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010229 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010230
Jeff Johnson295189b2012-06-20 16:38:30 -070010231 if (CSR_MAX_NUM_KEY <= key_index)
10232 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010233 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010234 key_index);
10235
10236 return -EINVAL;
10237 }
10238
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010239 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10240 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010241 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010242 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010243 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010244 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010245
Jeff Johnson295189b2012-06-20 16:38:30 -070010246 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010247 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010248 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010249 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010250 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080010251 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010252 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080010253 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070010254 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010255 {
10256 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070010257 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010258
Jeff Johnson295189b2012-06-20 16:38:30 -070010259 tCsrRoamSetKey setKey;
10260 v_U32_t roamId= 0xFF;
10261 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010262
10263 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010264 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010265
Jeff Johnson295189b2012-06-20 16:38:30 -070010266 Keys->defaultIndex = (u8)key_index;
10267 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10268 setKey.keyId = key_index;
10269 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010270
10271 vos_mem_copy(&setKey.Key[0],
10272 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010273 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010274
Gopichand Nakkala29149562013-05-10 21:43:41 +053010275 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010276
10277 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070010278 &pHddStaCtx->conn_info.bssId[0],
10279 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010280
Gopichand Nakkala29149562013-05-10 21:43:41 +053010281 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
10282 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
10283 eCSR_ENCRYPT_TYPE_WEP104)
10284 {
10285 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
10286 even though ap is configured for WEP-40 encryption. In this canse the key length
10287 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
10288 type(104) and switching encryption type to 40*/
10289 pWextState->roamProfile.EncryptionType.encryptionType[0] =
10290 eCSR_ENCRYPT_TYPE_WEP40;
10291 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
10292 eCSR_ENCRYPT_TYPE_WEP40;
10293 }
10294
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010295 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070010296 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010297
Jeff Johnson295189b2012-06-20 16:38:30 -070010298 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010299 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010300 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010301
Jeff Johnson295189b2012-06-20 16:38:30 -070010302 if ( 0 != status )
10303 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010304 hddLog(VOS_TRACE_LEVEL_ERROR,
10305 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010306 status);
10307 return -EINVAL;
10308 }
10309 }
10310 }
10311
10312 /* In SoftAp mode setting key direction for default mode */
10313 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
10314 {
10315 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
10316 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
10317 (eCSR_ENCRYPT_TYPE_AES !=
10318 pWextState->roamProfile.EncryptionType.encryptionType[0])
10319 )
10320 {
10321 /* Saving key direction for default key index to TX default */
10322 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
10323 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
10324 }
10325 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010326 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010327 return status;
10328}
10329
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010330#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10331static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
10332 struct net_device *ndev,
10333 u8 key_index,
10334 bool unicast, bool multicast)
10335#else
10336static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
10337 struct net_device *ndev,
10338 u8 key_index)
10339#endif
10340{
10341 int ret;
10342 vos_ssr_protect(__func__);
10343#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10344 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
10345 multicast);
10346#else
10347 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
10348#endif
10349 vos_ssr_unprotect(__func__);
10350
10351 return ret;
10352}
10353
Jeff Johnson295189b2012-06-20 16:38:30 -070010354/*
10355 * FUNCTION: wlan_hdd_cfg80211_inform_bss
10356 * This function is used to inform the BSS details to nl80211 interface.
10357 */
10358static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
10359 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
10360{
10361 struct net_device *dev = pAdapter->dev;
10362 struct wireless_dev *wdev = dev->ieee80211_ptr;
10363 struct wiphy *wiphy = wdev->wiphy;
10364 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
10365 int chan_no;
10366 int ie_length;
10367 const char *ie;
10368 unsigned int freq;
10369 struct ieee80211_channel *chan;
10370 int rssi = 0;
10371 struct cfg80211_bss *bss = NULL;
10372
Jeff Johnson295189b2012-06-20 16:38:30 -070010373 if( NULL == pBssDesc )
10374 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010375 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010376 return bss;
10377 }
10378
10379 chan_no = pBssDesc->channelId;
10380 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
10381 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
10382
10383 if( NULL == ie )
10384 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010385 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010386 return bss;
10387 }
10388
10389#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10390 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10391 {
10392 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10393 }
10394 else
10395 {
10396 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10397 }
10398#else
10399 freq = ieee80211_channel_to_frequency(chan_no);
10400#endif
10401
10402 chan = __ieee80211_get_channel(wiphy, freq);
10403
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053010404 if (!chan) {
10405 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
10406 return NULL;
10407 }
10408
Abhishek Singhaee43942014-06-16 18:55:47 +053010409 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070010410
Anand N Sunkad9f80b742015-07-30 20:05:51 +053010411 return cfg80211_inform_bss(wiphy, chan,
10412#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10413 CFG80211_BSS_FTYPE_UNKNOWN,
10414#endif
10415 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010416 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070010417 pBssDesc->capabilityInfo,
10418 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053010419 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070010420}
10421
10422
10423
10424/*
10425 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
10426 * This function is used to inform the BSS details to nl80211 interface.
10427 */
10428struct cfg80211_bss*
10429wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
10430 tSirBssDescription *bss_desc
10431 )
10432{
10433 /*
10434 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
10435 already exists in bss data base of cfg80211 for that particular BSS ID.
10436 Using cfg80211_inform_bss_frame to update the bss entry instead of
10437 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
10438 now there is no possibility to get the mgmt(probe response) frame from PE,
10439 converting bss_desc to ieee80211_mgmt(probe response) and passing to
10440 cfg80211_inform_bss_frame.
10441 */
10442 struct net_device *dev = pAdapter->dev;
10443 struct wireless_dev *wdev = dev->ieee80211_ptr;
10444 struct wiphy *wiphy = wdev->wiphy;
10445 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010446#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10447 qcom_ie_age *qie_age = NULL;
10448 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
10449#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010450 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010451#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010452 const char *ie =
10453 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
10454 unsigned int freq;
10455 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010456 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010457 struct cfg80211_bss *bss_status = NULL;
10458 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
10459 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070010460 hdd_context_t *pHddCtx;
10461 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070010462#ifdef WLAN_OPEN_SOURCE
10463 struct timespec ts;
10464#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010465
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010466
Wilson Yangf80a0542013-10-07 13:02:37 -070010467 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10468 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070010469 if (0 != status)
10470 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010471 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010472 }
10473
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010474 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070010475 if (!mgmt)
10476 {
10477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10478 "%s: memory allocation failed ", __func__);
10479 return NULL;
10480 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010481
Jeff Johnson295189b2012-06-20 16:38:30 -070010482 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010483
10484#ifdef WLAN_OPEN_SOURCE
10485 /* Android does not want the timestamp from the frame.
10486 Instead it wants a monotonic increasing value */
10487 get_monotonic_boottime(&ts);
10488 mgmt->u.probe_resp.timestamp =
10489 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
10490#else
10491 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010492 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
10493 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070010494
10495#endif
10496
Jeff Johnson295189b2012-06-20 16:38:30 -070010497 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
10498 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010499
10500#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10501 /* GPS Requirement: need age ie per entry. Using vendor specific. */
10502 /* Assuming this is the last IE, copy at the end */
10503 ie_length -=sizeof(qcom_ie_age);
10504 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
10505 qie_age->element_id = QCOM_VENDOR_IE_ID;
10506 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
10507 qie_age->oui_1 = QCOM_OUI1;
10508 qie_age->oui_2 = QCOM_OUI2;
10509 qie_age->oui_3 = QCOM_OUI3;
10510 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
10511 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
10512#endif
10513
Jeff Johnson295189b2012-06-20 16:38:30 -070010514 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053010515 if (bss_desc->fProbeRsp)
10516 {
10517 mgmt->frame_control |=
10518 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
10519 }
10520 else
10521 {
10522 mgmt->frame_control |=
10523 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
10524 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010525
10526#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010527 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010528 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
10529 {
10530 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10531 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010532 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010533 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
10534
10535 {
10536 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10537 }
10538 else
10539 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010540 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
10541 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070010542 kfree(mgmt);
10543 return NULL;
10544 }
10545#else
10546 freq = ieee80211_channel_to_frequency(chan_no);
10547#endif
10548 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010549 /*when the band is changed on the fly using the GUI, three things are done
10550 * 1. scan abort 2.flush scan results from cache 3.update the band with the new band user specified(refer to the hdd_setBand_helper function)
10551 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
10552 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
10553 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
10554 * and discards the channels correponding to previous band and calls back with zero bss results.
10555 * but if the time between band update and scan done callback is very small then band change will not reflect in SME and SME reports to HDD
10556 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
10557 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
10558 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
10559 * So drop the bss and continue to next bss.
10560 */
10561 if(chan == NULL)
10562 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010563 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070010564 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010565 return NULL;
10566 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053010567 /*To keep the rssi icon of the connected AP in the scan window
10568 *and the rssi icon of the wireless networks in sync
10569 * */
10570 if (( eConnectionState_Associated ==
10571 pAdapter->sessionCtx.station.conn_info.connState ) &&
10572 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
10573 pAdapter->sessionCtx.station.conn_info.bssId,
10574 WNI_CFG_BSSID_LEN)) &&
10575 (pHddCtx->hdd_wlan_suspended == FALSE))
10576 {
10577 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
10578 rssi = (pAdapter->rssi * 100);
10579 }
10580 else
10581 {
10582 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
10583 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010584
Nirav Shah20ac06f2013-12-12 18:14:06 +053010585 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053010586 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
10587 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053010588
Jeff Johnson295189b2012-06-20 16:38:30 -070010589 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
10590 frame_len, rssi, GFP_KERNEL);
10591 kfree(mgmt);
10592 return bss_status;
10593}
10594
10595/*
10596 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
10597 * This function is used to update the BSS data base of CFG8011
10598 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010599struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010600 tCsrRoamInfo *pRoamInfo
10601 )
10602{
10603 tCsrRoamConnectedProfile roamProfile;
10604 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10605 struct cfg80211_bss *bss = NULL;
10606
10607 ENTER();
10608
10609 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
10610 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
10611
10612 if (NULL != roamProfile.pBssDesc)
10613 {
Girish Gowlif4b68022014-08-28 23:18:57 +053010614 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10615 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070010616
10617 if (NULL == bss)
10618 {
10619 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
10620 __func__);
10621 }
10622
10623 sme_RoamFreeConnectProfile(hHal, &roamProfile);
10624 }
10625 else
10626 {
10627 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
10628 __func__);
10629 }
10630 return bss;
10631}
10632
10633/*
10634 * FUNCTION: wlan_hdd_cfg80211_update_bss
10635 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010636static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
10637 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070010638 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010639{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010640 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010641 tCsrScanResultInfo *pScanResult;
10642 eHalStatus status = 0;
10643 tScanResultHandle pResult;
10644 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010645 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010646 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070010647 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010648
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010649 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10650 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
10651 NO_SESSION, pAdapter->sessionId));
10652
Wilson Yangf80a0542013-10-07 13:02:37 -070010653 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10654
10655 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070010656 {
Wilson Yangf80a0542013-10-07 13:02:37 -070010657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10658 "%s:LOGP in Progress. Ignore!!!",__func__);
10659 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010660 }
10661
Wilson Yangf80a0542013-10-07 13:02:37 -070010662
10663 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053010664 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070010665 {
10666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10667 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
10668 return VOS_STATUS_E_PERM;
10669 }
10670
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010671 if (pAdapter->request != NULL)
10672 {
10673 if ((pAdapter->request->n_ssids == 1)
10674 && (pAdapter->request->ssids != NULL)
10675 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
10676 is_p2p_scan = true;
10677 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010678 /*
10679 * start getting scan results and populate cgf80211 BSS database
10680 */
10681 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
10682
10683 /* no scan results */
10684 if (NULL == pResult)
10685 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010686 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
10687 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053010688 wlan_hdd_get_frame_logs(pAdapter,
10689 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070010690 return status;
10691 }
10692
10693 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
10694
10695 while (pScanResult)
10696 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010697 /*
10698 * cfg80211_inform_bss() is not updating ie field of bss entry, if
10699 * entry already exists in bss data base of cfg80211 for that
10700 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
10701 * bss entry instead of cfg80211_inform_bss, But this call expects
10702 * mgmt packet as input. As of now there is no possibility to get
10703 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070010704 * ieee80211_mgmt(probe response) and passing to c
10705 * fg80211_inform_bss_frame.
10706 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010707 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
10708 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
10709 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010710 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10711 continue; //Skip the non p2p bss entries
10712 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010713 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10714 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010715
Jeff Johnson295189b2012-06-20 16:38:30 -070010716
10717 if (NULL == bss_status)
10718 {
10719 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010720 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010721 }
10722 else
10723 {
Yue Maf49ba872013-08-19 12:04:25 -070010724 cfg80211_put_bss(
10725#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
10726 wiphy,
10727#endif
10728 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010729 }
10730
10731 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10732 }
10733
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010734 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010735 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010736 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010737}
10738
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010739void
10740hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
10741{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010742 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080010743 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010744} /****** end hddPrintMacAddr() ******/
10745
10746void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010747hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010748{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010749 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010750 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010751 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
10752 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
10753 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010754} /****** end hddPrintPmkId() ******/
10755
10756//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
10757//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
10758
10759//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
10760//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
10761
10762#define dump_bssid(bssid) \
10763 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010764 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
10765 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010766 }
10767
10768#define dump_pmkid(pMac, pmkid) \
10769 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010770 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
10771 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010772 }
10773
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070010774#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010775/*
10776 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
10777 * This function is used to notify the supplicant of a new PMKSA candidate.
10778 */
10779int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010780 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010781 int index, bool preauth )
10782{
Jeff Johnsone7245742012-09-05 17:12:55 -070010783#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010784 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010785 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010786
10787 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070010788 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010789
10790 if( NULL == pRoamInfo )
10791 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010792 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010793 return -EINVAL;
10794 }
10795
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010796 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
10797 {
10798 dump_bssid(pRoamInfo->bssid);
10799 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010800 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010801 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010802#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010803 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010804}
10805#endif //FEATURE_WLAN_LFR
10806
Yue Maef608272013-04-08 23:09:17 -070010807#ifdef FEATURE_WLAN_LFR_METRICS
10808/*
10809 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
10810 * 802.11r/LFR metrics reporting function to report preauth initiation
10811 *
10812 */
10813#define MAX_LFR_METRICS_EVENT_LENGTH 100
10814VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
10815 tCsrRoamInfo *pRoamInfo)
10816{
10817 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10818 union iwreq_data wrqu;
10819
10820 ENTER();
10821
10822 if (NULL == pAdapter)
10823 {
10824 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10825 return VOS_STATUS_E_FAILURE;
10826 }
10827
10828 /* create the event */
10829 memset(&wrqu, 0, sizeof(wrqu));
10830 memset(metrics_notification, 0, sizeof(metrics_notification));
10831
10832 wrqu.data.pointer = metrics_notification;
10833 wrqu.data.length = scnprintf(metrics_notification,
10834 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
10835 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10836
10837 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10838
10839 EXIT();
10840
10841 return VOS_STATUS_SUCCESS;
10842}
10843
10844/*
10845 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
10846 * 802.11r/LFR metrics reporting function to report preauth completion
10847 * or failure
10848 */
10849VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
10850 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
10851{
10852 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10853 union iwreq_data wrqu;
10854
10855 ENTER();
10856
10857 if (NULL == pAdapter)
10858 {
10859 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10860 return VOS_STATUS_E_FAILURE;
10861 }
10862
10863 /* create the event */
10864 memset(&wrqu, 0, sizeof(wrqu));
10865 memset(metrics_notification, 0, sizeof(metrics_notification));
10866
10867 scnprintf(metrics_notification, sizeof(metrics_notification),
10868 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
10869 MAC_ADDR_ARRAY(pRoamInfo->bssid));
10870
10871 if (1 == preauth_status)
10872 strncat(metrics_notification, " TRUE", 5);
10873 else
10874 strncat(metrics_notification, " FALSE", 6);
10875
10876 wrqu.data.pointer = metrics_notification;
10877 wrqu.data.length = strlen(metrics_notification);
10878
10879 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10880
10881 EXIT();
10882
10883 return VOS_STATUS_SUCCESS;
10884}
10885
10886/*
10887 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
10888 * 802.11r/LFR metrics reporting function to report handover initiation
10889 *
10890 */
10891VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
10892 tCsrRoamInfo *pRoamInfo)
10893{
10894 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10895 union iwreq_data wrqu;
10896
10897 ENTER();
10898
10899 if (NULL == pAdapter)
10900 {
10901 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10902 return VOS_STATUS_E_FAILURE;
10903 }
10904
10905 /* create the event */
10906 memset(&wrqu, 0, sizeof(wrqu));
10907 memset(metrics_notification, 0, sizeof(metrics_notification));
10908
10909 wrqu.data.pointer = metrics_notification;
10910 wrqu.data.length = scnprintf(metrics_notification,
10911 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
10912 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10913
10914 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10915
10916 EXIT();
10917
10918 return VOS_STATUS_SUCCESS;
10919}
10920#endif
10921
Jeff Johnson295189b2012-06-20 16:38:30 -070010922/*
10923 * FUNCTION: hdd_cfg80211_scan_done_callback
10924 * scanning callback function, called after finishing scan
10925 *
10926 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010927static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070010928 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
10929{
10930 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010931 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070010932 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010933 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010934 struct cfg80211_scan_request *req = NULL;
10935 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010936 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010937 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010938 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010939 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010940
10941 ENTER();
10942
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010943 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053010944 if (NULL == pHddCtx) {
10945 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010946 goto allow_suspend;
10947 }
10948
10949 pScanInfo = &pHddCtx->scan_info;
10950
Jeff Johnson295189b2012-06-20 16:38:30 -070010951 hddLog(VOS_TRACE_LEVEL_INFO,
10952 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080010953 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010954 __func__, halHandle, pContext, (int) scanId, (int) status);
10955
Kiet Lamac06e2c2013-10-23 16:25:07 +053010956 pScanInfo->mScanPendingCounter = 0;
10957
Jeff Johnson295189b2012-06-20 16:38:30 -070010958 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010959 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010960 &pScanInfo->scan_req_completion_event,
10961 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010962 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070010963 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010964 hddLog(VOS_TRACE_LEVEL_ERROR,
10965 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070010966 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010967 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010968 }
10969
Yue Maef608272013-04-08 23:09:17 -070010970 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010971 {
10972 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010973 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010974 }
10975
10976 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010977 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070010978 {
10979 hddLog(VOS_TRACE_LEVEL_INFO,
10980 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010981 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070010982 (int) scanId);
10983 }
10984
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010985 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010986 pAdapter);
10987
10988 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010989 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010990
10991
10992 /* If any client wait scan result through WEXT
10993 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010994 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070010995 {
10996 /* The other scan request waiting for current scan finish
10997 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010998 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010999 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011000 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070011001 }
11002 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011003 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070011004 {
11005 struct net_device *dev = pAdapter->dev;
11006 union iwreq_data wrqu;
11007 int we_event;
11008 char *msg;
11009
11010 memset(&wrqu, '\0', sizeof(wrqu));
11011 we_event = SIOCGIWSCAN;
11012 msg = NULL;
11013 wireless_send_event(dev, we_event, &wrqu, msg);
11014 }
11015 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011016 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011017
11018 /* Get the Scan Req */
11019 req = pAdapter->request;
11020
11021 if (!req)
11022 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011023 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011024 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011025 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011026 }
11027
Jeff Johnson295189b2012-06-20 16:38:30 -070011028 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011029 /* Scan is no longer pending */
11030 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011031
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011032 /* last_scan_timestamp is used to decide if new scan
11033 * is needed or not on station interface. If last station
11034 * scan time and new station scan time is less then
11035 * last_scan_timestamp ; driver will return cached scan.
11036 */
11037 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
11038 {
11039 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
11040
11041 if ( req->n_channels )
11042 {
11043 for (i = 0; i < req->n_channels ; i++ )
11044 {
11045 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
11046 }
11047 /* store no of channel scanned */
11048 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
11049 }
11050
11051 }
11052
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070011053 /*
11054 * cfg80211_scan_done informing NL80211 about completion
11055 * of scanning
11056 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011057 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
11058 {
11059 aborted = true;
11060 }
11061 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080011062 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070011063
Siddharth Bhal76972212014-10-15 16:22:51 +053011064 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
11065 /* Generate new random mac addr for next scan */
11066 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
11067 hdd_processSpoofMacAddrRequest(pHddCtx);
11068 }
11069
Jeff Johnsone7245742012-09-05 17:12:55 -070011070allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011071 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011072 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011073
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011074 /* Acquire wakelock to handle the case where APP's tries to suspend
11075 * immediatly after the driver gets connect request(i.e after scan)
11076 * from supplicant, this result in app's is suspending and not able
11077 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011078 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011079
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070011080#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011081 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070011082#endif
11083
Jeff Johnson295189b2012-06-20 16:38:30 -070011084 EXIT();
11085 return 0;
11086}
11087
11088/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053011089 * FUNCTION: hdd_isConnectionInProgress
11090 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011091 *
11092 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011093v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011094{
11095 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11096 hdd_station_ctx_t *pHddStaCtx = NULL;
11097 hdd_adapter_t *pAdapter = NULL;
11098 VOS_STATUS status = 0;
11099 v_U8_t staId = 0;
11100 v_U8_t *staMac = NULL;
11101
c_hpothu9b781ba2013-12-30 20:57:45 +053011102 if (TRUE == pHddCtx->btCoexModeSet)
11103 {
11104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053011105 FL("BTCoex Mode operation in progress"));
11106 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053011107 }
11108
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011109 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11110
11111 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11112 {
11113 pAdapter = pAdapterNode->pAdapter;
11114
11115 if( pAdapter )
11116 {
11117 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011118 "%s: Adapter with device mode %s (%d) exists",
11119 __func__, hdd_device_modetoString(pAdapter->device_mode),
11120 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011121 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053011122 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11123 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
11124 (eConnectionState_Connecting ==
11125 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11126 {
11127 hddLog(VOS_TRACE_LEVEL_ERROR,
11128 "%s: %p(%d) Connection is in progress", __func__,
11129 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11130 return VOS_TRUE;
11131 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011132 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053011133 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011134 {
11135 hddLog(VOS_TRACE_LEVEL_ERROR,
11136 "%s: %p(%d) Reassociation is in progress", __func__,
11137 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11138 return VOS_TRUE;
11139 }
11140 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011141 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11142 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011143 {
11144 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11145 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011146 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011147 {
11148 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
11149 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011150 "%s: client " MAC_ADDRESS_STR
11151 " is in the middle of WPS/EAPOL exchange.", __func__,
11152 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011153 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011154 }
11155 }
11156 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
11157 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
11158 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011159 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11160 ptSapContext pSapCtx = NULL;
11161 pSapCtx = VOS_GET_SAP_CB(pVosContext);
11162 if(pSapCtx == NULL){
11163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11164 FL("psapCtx is NULL"));
11165 return VOS_FALSE;
11166 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011167 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
11168 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011169 if ((pSapCtx->aStaInfo[staId].isUsed) &&
11170 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011171 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011172 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011173
11174 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011175 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
11176 "middle of WPS/EAPOL exchange.", __func__,
11177 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011178 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011179 }
11180 }
11181 }
11182 }
11183 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11184 pAdapterNode = pNext;
11185 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053011186 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011187}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011188
11189/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011190 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070011191 * this scan respond to scan trigger and update cfg80211 scan database
11192 * later, scan dump command can be used to recieve scan results
11193 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011194int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080011195#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11196 struct net_device *dev,
11197#endif
11198 struct cfg80211_scan_request *request)
11199{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011200 hdd_adapter_t *pAdapter = NULL;
11201 hdd_context_t *pHddCtx = NULL;
11202 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011203 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011204 tCsrScanRequest scanRequest;
11205 tANI_U8 *channelList = NULL, i;
11206 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011207 int status;
11208 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011209 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011210 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053011211 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011212 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011213 v_S7_t rssi=0;
11214 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011215
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011216#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
11217 struct net_device *dev = NULL;
11218 if (NULL == request)
11219 {
11220 hddLog(VOS_TRACE_LEVEL_ERROR,
11221 "%s: scan req param null", __func__);
11222 return -EINVAL;
11223 }
11224 dev = request->wdev->netdev;
11225#endif
11226
11227 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11228 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
11229 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11230
Jeff Johnson295189b2012-06-20 16:38:30 -070011231 ENTER();
11232
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011233 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11234 __func__, hdd_device_modetoString(pAdapter->device_mode),
11235 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011236
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011237 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011238 if (0 != status)
11239 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011240 return status;
11241 }
11242
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011243 if (NULL == pwextBuf)
11244 {
11245 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
11246 __func__);
11247 return -EIO;
11248 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011249 cfg_param = pHddCtx->cfg_ini;
11250 pScanInfo = &pHddCtx->scan_info;
11251
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011252 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11253 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
11254 {
11255 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
11256 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
11257 }
11258
Jeff Johnson295189b2012-06-20 16:38:30 -070011259#ifdef WLAN_BTAMP_FEATURE
11260 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011261 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070011262 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011263 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011264 "%s: No scanning when AMP is on", __func__);
11265 return -EOPNOTSUPP;
11266 }
11267#endif
11268 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011269 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011270 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011271 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011272 "%s: Not scanning on device_mode = %s (%d)",
11273 __func__, hdd_device_modetoString(pAdapter->device_mode),
11274 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011275 return -EOPNOTSUPP;
11276 }
11277
11278 if (TRUE == pScanInfo->mScanPending)
11279 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053011280 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
11281 {
11282 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
11283 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011284 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070011285 }
11286
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053011287 // Don't allow scan if PNO scan is going on.
11288 if (pHddCtx->isPnoEnable)
11289 {
11290 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11291 FL("pno scan in progress"));
11292 return -EBUSY;
11293 }
11294
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011295 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070011296 //Channel and action frame is pending
11297 //Otherwise Cancel Remain On Channel and allow Scan
11298 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011299 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070011300 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053011301 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011302 return -EBUSY;
11303 }
11304
Jeff Johnson295189b2012-06-20 16:38:30 -070011305 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
11306 {
11307 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080011308 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011309 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011310 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011311 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
11312 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011313 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011314 "%s: MAX TM Level Scan not allowed", __func__);
11315 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011316 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070011317 }
11318 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
11319
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011320 /* Check if scan is allowed at this point of time.
11321 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011322 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011323 {
11324 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
11325 return -EBUSY;
11326 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011327
Jeff Johnson295189b2012-06-20 16:38:30 -070011328 vos_mem_zero( &scanRequest, sizeof(scanRequest));
11329
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011330 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
11331 * Becasue of this, driver is assuming that this is not wildcard scan and so
11332 * is not aging out the scan results.
11333 */
11334 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011335 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011336 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011337 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011338
11339 if ((request->ssids) && (0 < request->n_ssids))
11340 {
11341 tCsrSSIDInfo *SsidInfo;
11342 int j;
11343 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
11344 /* Allocate num_ssid tCsrSSIDInfo structure */
11345 SsidInfo = scanRequest.SSIDs.SSIDList =
11346 ( tCsrSSIDInfo *)vos_mem_malloc(
11347 request->n_ssids*sizeof(tCsrSSIDInfo));
11348
11349 if(NULL == scanRequest.SSIDs.SSIDList)
11350 {
11351 hddLog(VOS_TRACE_LEVEL_ERROR,
11352 "%s: memory alloc failed SSIDInfo buffer", __func__);
11353 return -ENOMEM;
11354 }
11355
11356 /* copy all the ssid's and their length */
11357 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
11358 {
11359 /* get the ssid length */
11360 SsidInfo->SSID.length = request->ssids[j].ssid_len;
11361 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
11362 SsidInfo->SSID.length);
11363 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
11364 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
11365 j, SsidInfo->SSID.ssId);
11366 }
11367 /* set the scan type to active */
11368 scanRequest.scanType = eSIR_ACTIVE_SCAN;
11369 }
11370 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011371 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011372 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11373 TRACE_CODE_HDD_CFG80211_SCAN,
11374 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070011375 /* set the scan type to active */
11376 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070011377 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011378 else
11379 {
11380 /*Set the scan type to default type, in this case it is ACTIVE*/
11381 scanRequest.scanType = pScanInfo->scan_mode;
11382 }
11383 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
11384 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070011385
11386 /* set BSSType to default type */
11387 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
11388
11389 /*TODO: scan the requested channels only*/
11390
11391 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011392 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070011393 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011394 hddLog(VOS_TRACE_LEVEL_WARN,
11395 "No of Scan Channels exceeded limit: %d", request->n_channels);
11396 request->n_channels = MAX_CHANNEL;
11397 }
11398
11399 hddLog(VOS_TRACE_LEVEL_INFO,
11400 "No of Scan Channels: %d", request->n_channels);
11401
11402
11403 if( request->n_channels )
11404 {
11405 char chList [(request->n_channels*5)+1];
11406 int len;
11407 channelList = vos_mem_malloc( request->n_channels );
11408 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053011409 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011410 hddLog(VOS_TRACE_LEVEL_ERROR,
11411 "%s: memory alloc failed channelList", __func__);
11412 status = -ENOMEM;
11413 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053011414 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011415
11416 for( i = 0, len = 0; i < request->n_channels ; i++ )
11417 {
11418 channelList[i] = request->channels[i]->hw_value;
11419 len += snprintf(chList+len, 5, "%d ", channelList[i]);
11420 }
11421
Nirav Shah20ac06f2013-12-12 18:14:06 +053011422 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011423 "Channel-List: %s ", chList);
11424 }
c_hpothu53512302014-04-15 18:49:53 +053011425
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011426 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
11427 scanRequest.ChannelInfo.ChannelList = channelList;
11428
11429 /* set requestType to full scan */
11430 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11431
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011432 /* if there is back to back scan happening in driver with in
11433 * nDeferScanTimeInterval interval driver should defer new scan request
11434 * and should provide last cached scan results instead of new channel list.
11435 * This rule is not applicable if scan is p2p scan.
11436 * This condition will work only in case when last request no of channels
11437 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053011438 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053011439 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011440 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011441
Sushant Kaushik86592172015-04-27 16:35:03 +053011442 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
11443 /* if wps ie is NULL , then only defer scan */
11444 if ( pWpsIe == NULL &&
11445 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053011446 {
11447 if ( pScanInfo->last_scan_timestamp !=0 &&
11448 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
11449 {
11450 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
11451 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
11452 vos_mem_compare(pScanInfo->last_scan_channelList,
11453 channelList, pScanInfo->last_scan_numChannels))
11454 {
11455 hddLog(VOS_TRACE_LEVEL_WARN,
11456 " New and old station scan time differ is less then %u",
11457 pHddCtx->cfg_ini->nDeferScanTimeInterval);
11458
11459 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011460 pAdapter);
11461
Agarwal Ashish57e84372014-12-05 18:26:53 +053011462 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011463 "Return old cached scan as all channels and no of channels are same");
11464
Agarwal Ashish57e84372014-12-05 18:26:53 +053011465 if (0 > ret)
11466 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011467
Agarwal Ashish57e84372014-12-05 18:26:53 +053011468 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011469
11470 status = eHAL_STATUS_SUCCESS;
11471 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053011472 }
11473 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011474 }
11475
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011476 /* Flush the scan results(only p2p beacons) for STA scan and P2P
11477 * search (Flush on both full scan and social scan but not on single
11478 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
11479 */
11480
11481 /* Supplicant does single channel scan after 8-way handshake
11482 * and in that case driver shoudnt flush scan results. If
11483 * driver flushes the scan results here and unfortunately if
11484 * the AP doesnt respond to our probe req then association
11485 * fails which is not desired
11486 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011487 if ((request->n_ssids == 1)
11488 && (request->ssids != NULL)
11489 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
11490 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011491
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011492 if( is_p2p_scan ||
11493 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011494 {
11495 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
11496 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
11497 pAdapter->sessionId );
11498 }
11499
11500 if( request->ie_len )
11501 {
11502 /* save this for future association (join requires this) */
11503 /*TODO: Array needs to be converted to dynamic allocation,
11504 * as multiple ie.s can be sent in cfg80211_scan_request structure
11505 * CR 597966
11506 */
11507 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
11508 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
11509 pScanInfo->scanAddIE.length = request->ie_len;
11510
11511 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11512 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11513 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011514 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011515 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070011516 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011517 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
11518 memcpy( pwextBuf->roamProfile.addIEScan,
11519 request->ie, request->ie_len);
11520 }
11521 else
11522 {
11523 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
11524 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011525 }
11526
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011527 }
11528 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
11529 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
11530
11531 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
11532 request->ie_len);
11533 if (pP2pIe != NULL)
11534 {
11535#ifdef WLAN_FEATURE_P2P_DEBUG
11536 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
11537 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
11538 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053011539 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011540 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
11541 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11542 "Go nego completed to Connection is started");
11543 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11544 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053011545 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011546 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
11547 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011548 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011549 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
11550 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11551 "Disconnected state to Connection is started");
11552 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11553 "for 4way Handshake");
11554 }
11555#endif
11556
11557 /* no_cck will be set during p2p find to disable 11b rates */
11558 if(TRUE == request->no_cck)
11559 {
11560 hddLog(VOS_TRACE_LEVEL_INFO,
11561 "%s: This is a P2P Search", __func__);
11562 scanRequest.p2pSearch = 1;
11563
11564 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053011565 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011566 /* set requestType to P2P Discovery */
11567 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
11568 }
11569
11570 /*
11571 Skip Dfs Channel in case of P2P Search
11572 if it is set in ini file
11573 */
11574 if(cfg_param->skipDfsChnlInP2pSearch)
11575 {
11576 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011577 }
11578 else
11579 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011580 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011581 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011582
Agarwal Ashish4f616132013-12-30 23:32:50 +053011583 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011584 }
11585 }
11586
11587 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
11588
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011589#ifdef FEATURE_WLAN_TDLS
11590 /* if tdls disagree scan right now, return immediately.
11591 tdls will schedule the scan when scan is allowed. (return SUCCESS)
11592 or will reject the scan if any TDLS is in progress. (return -EBUSY)
11593 */
11594 status = wlan_hdd_tdls_scan_callback (pAdapter,
11595 wiphy,
11596#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11597 dev,
11598#endif
11599 request);
11600 if(status <= 0)
11601 {
11602 if(!status)
11603 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
11604 "scan rejected %d", __func__, status);
11605 else
11606 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
11607 __func__, status);
11608
11609 return status;
11610 }
11611#endif
11612
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011613 /* acquire the wakelock to avoid the apps suspend during the scan. To
11614 * address the following issues.
11615 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
11616 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
11617 * for long time, this result in apps running at full power for long time.
11618 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
11619 * be stuck in full power because of resume BMPS
11620 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011621 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011622
Nirav Shah20ac06f2013-12-12 18:14:06 +053011623 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11624 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011625 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
11626 scanRequest.requestType, scanRequest.scanType,
11627 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053011628 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
11629
Siddharth Bhal76972212014-10-15 16:22:51 +053011630 if (pHddCtx->spoofMacAddr.isEnabled)
11631 {
11632 hddLog(VOS_TRACE_LEVEL_INFO,
11633 "%s: MAC Spoofing enabled for current scan", __func__);
11634 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
11635 * to fill TxBds for probe request during current scan
11636 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011637 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053011638 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011639
11640 if(status != VOS_STATUS_SUCCESS)
11641 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011642 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011643 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053011644#ifdef FEATURE_WLAN_TDLS
11645 wlan_hdd_tdls_scan_done_callback(pAdapter);
11646#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011647 goto free_mem;
11648 }
Siddharth Bhal76972212014-10-15 16:22:51 +053011649 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053011650 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070011651 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011652 pAdapter->sessionId, &scanRequest, &scanId,
11653 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070011654
Jeff Johnson295189b2012-06-20 16:38:30 -070011655 if (eHAL_STATUS_SUCCESS != status)
11656 {
11657 hddLog(VOS_TRACE_LEVEL_ERROR,
11658 "%s: sme_ScanRequest returned error %d", __func__, status);
11659 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011660 if(eHAL_STATUS_RESOURCES == status)
11661 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011662 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
11663 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011664 status = -EBUSY;
11665 } else {
11666 status = -EIO;
11667 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011668 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011669
11670#ifdef FEATURE_WLAN_TDLS
11671 wlan_hdd_tdls_scan_done_callback(pAdapter);
11672#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011673 goto free_mem;
11674 }
11675
11676 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011677 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011678 pAdapter->request = request;
11679 pScanInfo->scanId = scanId;
11680
11681 complete(&pScanInfo->scan_req_completion_event);
11682
11683free_mem:
11684 if( scanRequest.SSIDs.SSIDList )
11685 {
11686 vos_mem_free(scanRequest.SSIDs.SSIDList);
11687 }
11688
11689 if( channelList )
11690 vos_mem_free( channelList );
11691
11692 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011693 return status;
11694}
11695
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011696int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
11697#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11698 struct net_device *dev,
11699#endif
11700 struct cfg80211_scan_request *request)
11701{
11702 int ret;
11703
11704 vos_ssr_protect(__func__);
11705 ret = __wlan_hdd_cfg80211_scan(wiphy,
11706#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11707 dev,
11708#endif
11709 request);
11710 vos_ssr_unprotect(__func__);
11711
11712 return ret;
11713}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011714
11715void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
11716{
11717 v_U8_t iniDot11Mode =
11718 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
11719 eHddDot11Mode hddDot11Mode = iniDot11Mode;
11720
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011721 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
11722 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011723 switch ( iniDot11Mode )
11724 {
11725 case eHDD_DOT11_MODE_AUTO:
11726 case eHDD_DOT11_MODE_11ac:
11727 case eHDD_DOT11_MODE_11ac_ONLY:
11728#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053011729 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
11730 sme_IsFeatureSupportedByFW(DOT11AC) )
11731 hddDot11Mode = eHDD_DOT11_MODE_11ac;
11732 else
11733 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011734#else
11735 hddDot11Mode = eHDD_DOT11_MODE_11n;
11736#endif
11737 break;
11738 case eHDD_DOT11_MODE_11n:
11739 case eHDD_DOT11_MODE_11n_ONLY:
11740 hddDot11Mode = eHDD_DOT11_MODE_11n;
11741 break;
11742 default:
11743 hddDot11Mode = iniDot11Mode;
11744 break;
11745 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011746#ifdef WLAN_FEATURE_AP_HT40_24G
11747 if (operationChannel > SIR_11B_CHANNEL_END)
11748#endif
11749 {
11750 /* This call decides required channel bonding mode */
11751 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011752 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
11753 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011754 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011755}
11756
Jeff Johnson295189b2012-06-20 16:38:30 -070011757/*
11758 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011759 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011760 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011761int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053011762 const u8 *ssid, size_t ssid_len, const u8 *bssid,
11763 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070011764{
11765 int status = 0;
11766 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080011767 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011768 v_U32_t roamId;
11769 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070011770 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053011771 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011772
11773 ENTER();
11774
11775 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080011776 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11777
11778 status = wlan_hdd_validate_context(pHddCtx);
11779 if (status)
11780 {
Yue Mae36e3552014-03-05 17:06:20 -080011781 return status;
11782 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011783
Jeff Johnson295189b2012-06-20 16:38:30 -070011784 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
11785 {
11786 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
11787 return -EINVAL;
11788 }
11789
11790 pRoamProfile = &pWextState->roamProfile;
11791
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011792 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070011793 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011794 hdd_station_ctx_t *pHddStaCtx;
11795 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011796
Siddharth Bhalda0d1622015-04-24 15:47:49 +053011797 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
11798
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011799 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070011800 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
11801 {
11802 /*QoS not enabled in cfg file*/
11803 pRoamProfile->uapsd_mask = 0;
11804 }
11805 else
11806 {
11807 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011808 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070011809 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
11810 }
11811
11812 pRoamProfile->SSIDs.numOfSSIDs = 1;
11813 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
11814 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011815 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070011816 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
11817 ssid, ssid_len);
11818
11819 if (bssid)
11820 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053011821 pValidBssid = bssid;
11822 }
11823 else if (bssid_hint)
11824 {
11825 pValidBssid = bssid_hint;
11826 }
11827 if (pValidBssid)
11828 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011829 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053011830 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070011831 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011832 /* Save BSSID in seperate variable as well, as RoamProfile
11833 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070011834 case of join failure we should send valid BSSID to supplicant
11835 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053011836 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070011837 WNI_CFG_BSSID_LEN);
11838 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070011839 else
11840 {
11841 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
11842 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011843
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011844 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
11845 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011846 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
11847 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011848 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011849 /*set gen ie*/
11850 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
11851 /*set auth*/
11852 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
11853 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011854#ifdef FEATURE_WLAN_WAPI
11855 if (pAdapter->wapi_info.nWapiMode)
11856 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011857 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011858 switch (pAdapter->wapi_info.wapiAuthMode)
11859 {
11860 case WAPI_AUTH_MODE_PSK:
11861 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011862 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011863 pAdapter->wapi_info.wapiAuthMode);
11864 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
11865 break;
11866 }
11867 case WAPI_AUTH_MODE_CERT:
11868 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011869 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011870 pAdapter->wapi_info.wapiAuthMode);
11871 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
11872 break;
11873 }
11874 } // End of switch
11875 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
11876 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
11877 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011878 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011879 pRoamProfile->AuthType.numEntries = 1;
11880 pRoamProfile->EncryptionType.numEntries = 1;
11881 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11882 pRoamProfile->mcEncryptionType.numEntries = 1;
11883 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11884 }
11885 }
11886#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011887#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011888 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011889 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11890 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
11891 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011892 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
11893 sizeof (tSirGtkOffloadParams));
11894 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011895 }
11896#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011897 pRoamProfile->csrPersona = pAdapter->device_mode;
11898
Jeff Johnson32d95a32012-09-10 13:15:23 -070011899 if( operatingChannel )
11900 {
11901 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
11902 pRoamProfile->ChannelInfo.numOfChannels = 1;
11903 }
Chet Lanctot186b5732013-03-18 10:26:30 -070011904 else
11905 {
11906 pRoamProfile->ChannelInfo.ChannelList = NULL;
11907 pRoamProfile->ChannelInfo.numOfChannels = 0;
11908 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011909 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
11910 {
11911 hdd_select_cbmode(pAdapter,operatingChannel);
11912 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011913
Agarwal Ashish40f9b872015-09-01 16:17:35 +053011914 /*
11915 * Change conn_state to connecting before sme_RoamConnect(),
11916 * because sme_RoamConnect() has a direct path to call
11917 * hdd_smeRoamCallback(), which will change the conn_state
11918 * If direct path, conn_state will be accordingly changed
11919 * to NotConnected or Associated by either
11920 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
11921 * in sme_RoamCallback()
11922 * if sme_RomConnect is to be queued,
11923 * Connecting state will remain until it is completed.
11924 * If connection state is not changed,
11925 * connection state will remain in eConnectionState_NotConnected state.
11926 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
11927 * if conn state is eConnectionState_NotConnected.
11928 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
11929 * informed of connect result indication which is an issue.
11930 */
11931
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011932 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11933 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053011934 {
11935 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053011936 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011937 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
11938 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053011939 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011940 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011941 pAdapter->sessionId, pRoamProfile, &roamId);
11942
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011943 if ((eHAL_STATUS_SUCCESS != status) &&
11944 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11945 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011946
11947 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053011948 hddLog(VOS_TRACE_LEVEL_ERROR,
11949 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
11950 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011951 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011952 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011953 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011954 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011955
11956 pRoamProfile->ChannelInfo.ChannelList = NULL;
11957 pRoamProfile->ChannelInfo.numOfChannels = 0;
11958
Jeff Johnson295189b2012-06-20 16:38:30 -070011959 }
11960 else
11961 {
11962 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
11963 return -EINVAL;
11964 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011965 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011966 return status;
11967}
11968
11969/*
11970 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
11971 * This function is used to set the authentication type (OPEN/SHARED).
11972 *
11973 */
11974static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
11975 enum nl80211_auth_type auth_type)
11976{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011977 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011978 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11979
11980 ENTER();
11981
11982 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011983 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070011984 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011985 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011986 hddLog(VOS_TRACE_LEVEL_INFO,
11987 "%s: set authentication type to AUTOSWITCH", __func__);
11988 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
11989 break;
11990
11991 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011992#ifdef WLAN_FEATURE_VOWIFI_11R
11993 case NL80211_AUTHTYPE_FT:
11994#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011995 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011996 "%s: set authentication type to OPEN", __func__);
11997 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11998 break;
11999
12000 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012001 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012002 "%s: set authentication type to SHARED", __func__);
12003 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
12004 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012005#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012006 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012007 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012008 "%s: set authentication type to CCKM WPA", __func__);
12009 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
12010 break;
12011#endif
12012
12013
12014 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012015 hddLog(VOS_TRACE_LEVEL_ERROR,
12016 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012017 auth_type);
12018 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
12019 return -EINVAL;
12020 }
12021
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012022 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012023 pHddStaCtx->conn_info.authType;
12024 return 0;
12025}
12026
12027/*
12028 * FUNCTION: wlan_hdd_set_akm_suite
12029 * This function is used to set the key mgmt type(PSK/8021x).
12030 *
12031 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012032static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012033 u32 key_mgmt
12034 )
12035{
12036 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12037 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053012038 /* Should be in ieee802_11_defs.h */
12039#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
12040#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070012041 /*set key mgmt type*/
12042 switch(key_mgmt)
12043 {
12044 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053012045 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012046#ifdef WLAN_FEATURE_VOWIFI_11R
12047 case WLAN_AKM_SUITE_FT_PSK:
12048#endif
12049 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070012050 __func__);
12051 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
12052 break;
12053
12054 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053012055 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012056#ifdef WLAN_FEATURE_VOWIFI_11R
12057 case WLAN_AKM_SUITE_FT_8021X:
12058#endif
12059 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070012060 __func__);
12061 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
12062 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012063#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012064#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
12065#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
12066 case WLAN_AKM_SUITE_CCKM:
12067 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
12068 __func__);
12069 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
12070 break;
12071#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070012072#ifndef WLAN_AKM_SUITE_OSEN
12073#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
12074 case WLAN_AKM_SUITE_OSEN:
12075 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
12076 __func__);
12077 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
12078 break;
12079#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012080
12081 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012082 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012083 __func__, key_mgmt);
12084 return -EINVAL;
12085
12086 }
12087 return 0;
12088}
12089
12090/*
12091 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012092 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070012093 * (NONE/WEP40/WEP104/TKIP/CCMP).
12094 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012095static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
12096 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070012097 bool ucast
12098 )
12099{
12100 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012101 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012102 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12103
12104 ENTER();
12105
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012106 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012107 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012108 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070012109 __func__, cipher);
12110 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12111 }
12112 else
12113 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012114
Jeff Johnson295189b2012-06-20 16:38:30 -070012115 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012116 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012117 {
12118 case IW_AUTH_CIPHER_NONE:
12119 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12120 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012121
Jeff Johnson295189b2012-06-20 16:38:30 -070012122 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012123 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070012124 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012125
Jeff Johnson295189b2012-06-20 16:38:30 -070012126 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012127 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070012128 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012129
Jeff Johnson295189b2012-06-20 16:38:30 -070012130 case WLAN_CIPHER_SUITE_TKIP:
12131 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
12132 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012133
Jeff Johnson295189b2012-06-20 16:38:30 -070012134 case WLAN_CIPHER_SUITE_CCMP:
12135 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12136 break;
12137#ifdef FEATURE_WLAN_WAPI
12138 case WLAN_CIPHER_SUITE_SMS4:
12139 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
12140 break;
12141#endif
12142
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012143#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012144 case WLAN_CIPHER_SUITE_KRK:
12145 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
12146 break;
12147#endif
12148 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012149 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012150 __func__, cipher);
12151 return -EOPNOTSUPP;
12152 }
12153 }
12154
12155 if (ucast)
12156 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012157 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012158 __func__, encryptionType);
12159 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12160 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012161 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012162 encryptionType;
12163 }
12164 else
12165 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012166 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012167 __func__, encryptionType);
12168 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
12169 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
12170 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
12171 }
12172
12173 return 0;
12174}
12175
12176
12177/*
12178 * FUNCTION: wlan_hdd_cfg80211_set_ie
12179 * This function is used to parse WPA/RSN IE's.
12180 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012181int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012182#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12183 const u8 *ie,
12184#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012185 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012186#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012187 size_t ie_len
12188 )
12189{
12190 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012191#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12192 const u8 *genie = ie;
12193#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012194 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012195#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012196 v_U16_t remLen = ie_len;
12197#ifdef FEATURE_WLAN_WAPI
12198 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
12199 u16 *tmp;
12200 v_U16_t akmsuiteCount;
12201 int *akmlist;
12202#endif
12203 ENTER();
12204
12205 /* clear previous assocAddIE */
12206 pWextState->assocAddIE.length = 0;
12207 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012208 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012209
12210 while (remLen >= 2)
12211 {
12212 v_U16_t eLen = 0;
12213 v_U8_t elementId;
12214 elementId = *genie++;
12215 eLen = *genie++;
12216 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012217
Arif Hussain6d2a3322013-11-17 19:50:10 -080012218 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070012219 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012220
12221 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070012222 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012223 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012224 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 -070012225 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012226 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012227 "%s: Invalid WPA IE", __func__);
12228 return -EINVAL;
12229 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012230 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070012231 {
12232 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012233 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012234 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012235
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012236 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012237 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012238 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
12239 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012240 VOS_ASSERT(0);
12241 return -ENOMEM;
12242 }
12243 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12244 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12245 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012246
Jeff Johnson295189b2012-06-20 16:38:30 -070012247 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
12248 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12249 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12250 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012251 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
12252 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012253 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
12254 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12255 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
12256 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
12257 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
12258 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012259 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053012260 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070012261 {
12262 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012263 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012264 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012265
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012266 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012267 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012268 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12269 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012270 VOS_ASSERT(0);
12271 return -ENOMEM;
12272 }
12273 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12274 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12275 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012276
Jeff Johnson295189b2012-06-20 16:38:30 -070012277 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12278 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12279 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012280#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012281 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
12282 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012283 /*Consider WFD IE, only for P2P Client */
12284 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
12285 {
12286 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012287 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012288 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012289
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012290 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012291 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012292 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12293 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012294 VOS_ASSERT(0);
12295 return -ENOMEM;
12296 }
12297 // WFD IE is saved to Additional IE ; it should be accumulated to handle
12298 // WPS IE + P2P IE + WFD IE
12299 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12300 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012301
Jeff Johnson295189b2012-06-20 16:38:30 -070012302 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12303 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12304 }
12305#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012306 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012307 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012308 HS20_OUI_TYPE_SIZE)) )
12309 {
12310 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012311 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012312 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012313
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012314 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012315 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012316 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12317 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012318 VOS_ASSERT(0);
12319 return -ENOMEM;
12320 }
12321 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12322 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012323
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012324 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12325 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12326 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012327 /* Appending OSEN Information Element in Assiciation Request */
12328 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
12329 OSEN_OUI_TYPE_SIZE)) )
12330 {
12331 v_U16_t curAddIELen = pWextState->assocAddIE.length;
12332 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
12333 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012334
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012335 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012336 {
12337 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12338 "Need bigger buffer space");
12339 VOS_ASSERT(0);
12340 return -ENOMEM;
12341 }
12342 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12343 pWextState->assocAddIE.length += eLen + 2;
12344
12345 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
12346 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12347 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12348 }
12349
Abhishek Singh4322e622015-06-10 15:42:54 +053012350 /* Update only for WPA IE */
12351 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
12352 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012353
12354 /* populating as ADDIE in beacon frames */
12355 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012356 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012357 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
12358 {
12359 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12360 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
12361 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12362 {
12363 hddLog(LOGE,
12364 "Coldn't pass "
12365 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
12366 }
12367 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
12368 else
12369 hddLog(LOGE,
12370 "Could not pass on "
12371 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
12372
12373 /* IBSS mode doesn't contain params->proberesp_ies still
12374 beaconIE's need to be populated in probe response frames */
12375 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
12376 {
12377 u16 rem_probe_resp_ie_len = eLen + 2;
12378 u8 probe_rsp_ie_len[3] = {0};
12379 u8 counter = 0;
12380
12381 /* Check Probe Resp Length if it is greater then 255 then
12382 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
12383 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
12384 not able Store More then 255 bytes into One Variable */
12385
12386 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
12387 {
12388 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
12389 {
12390 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
12391 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
12392 }
12393 else
12394 {
12395 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
12396 rem_probe_resp_ie_len = 0;
12397 }
12398 }
12399
12400 rem_probe_resp_ie_len = 0;
12401
12402 if (probe_rsp_ie_len[0] > 0)
12403 {
12404 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12405 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
12406 (tANI_U8*)(genie - 2),
12407 probe_rsp_ie_len[0], NULL,
12408 eANI_BOOLEAN_FALSE)
12409 == eHAL_STATUS_FAILURE)
12410 {
12411 hddLog(LOGE,
12412 "Could not pass"
12413 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
12414 }
12415 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
12416 }
12417
12418 if (probe_rsp_ie_len[1] > 0)
12419 {
12420 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12421 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
12422 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12423 probe_rsp_ie_len[1], NULL,
12424 eANI_BOOLEAN_FALSE)
12425 == eHAL_STATUS_FAILURE)
12426 {
12427 hddLog(LOGE,
12428 "Could not pass"
12429 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
12430 }
12431 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
12432 }
12433
12434 if (probe_rsp_ie_len[2] > 0)
12435 {
12436 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12437 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
12438 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12439 probe_rsp_ie_len[2], NULL,
12440 eANI_BOOLEAN_FALSE)
12441 == eHAL_STATUS_FAILURE)
12442 {
12443 hddLog(LOGE,
12444 "Could not pass"
12445 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
12446 }
12447 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
12448 }
12449
12450 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12451 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
12452 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12453 {
12454 hddLog(LOGE,
12455 "Could not pass"
12456 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
12457 }
12458 }
12459 else
12460 {
12461 // Reset WNI_CFG_PROBE_RSP Flags
12462 wlan_hdd_reset_prob_rspies(pAdapter);
12463
12464 hddLog(VOS_TRACE_LEVEL_INFO,
12465 "%s: No Probe Response IE received in set beacon",
12466 __func__);
12467 }
12468 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012469 break;
12470 case DOT11F_EID_RSN:
12471 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
12472 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12473 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
12474 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
12475 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
12476 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053012477
12478 /* Appending Extended Capabilities with Interworking bit set
12479 * in Assoc Req.
12480 *
12481 * In assoc req this EXT Cap will only be taken into account if
12482 * interworkingService bit is set to 1. Currently
12483 * driver is only interested in interworkingService capability
12484 * from supplicant. If in future any other EXT Cap info is
12485 * required from supplicat, it needs to be handled while
12486 * sending Assoc Req in LIM.
12487 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012488 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012489 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012490 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012491 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012492 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012493
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012494 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012495 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012496 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12497 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012498 VOS_ASSERT(0);
12499 return -ENOMEM;
12500 }
12501 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12502 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012503
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012504 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12505 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12506 break;
12507 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012508#ifdef FEATURE_WLAN_WAPI
12509 case WLAN_EID_WAPI:
12510 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012511 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012512 pAdapter->wapi_info.nWapiMode);
12513 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012514 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070012515 akmsuiteCount = WPA_GET_LE16(tmp);
12516 tmp = tmp + 1;
12517 akmlist = (int *)(tmp);
12518 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
12519 {
12520 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
12521 }
12522 else
12523 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012524 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070012525 VOS_ASSERT(0);
12526 return -EINVAL;
12527 }
12528
12529 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
12530 {
12531 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012532 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012533 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012534 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012535 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012536 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012537 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012538 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012539 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
12540 }
12541 break;
12542#endif
12543 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012544 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012545 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012546 /* when Unknown IE is received we should break and continue
12547 * to the next IE in the buffer instead we were returning
12548 * so changing this to break */
12549 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070012550 }
12551 genie += eLen;
12552 remLen -= eLen;
12553 }
12554 EXIT();
12555 return 0;
12556}
12557
12558/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012559 * FUNCTION: hdd_isWPAIEPresent
12560 * Parse the received IE to find the WPA IE
12561 *
12562 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012563static bool hdd_isWPAIEPresent(
12564#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
12565 const u8 *ie,
12566#else
12567 u8 *ie,
12568#endif
12569 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012570{
12571 v_U8_t eLen = 0;
12572 v_U16_t remLen = ie_len;
12573 v_U8_t elementId = 0;
12574
12575 while (remLen >= 2)
12576 {
12577 elementId = *ie++;
12578 eLen = *ie++;
12579 remLen -= 2;
12580 if (eLen > remLen)
12581 {
12582 hddLog(VOS_TRACE_LEVEL_ERROR,
12583 "%s: IE length is wrong %d", __func__, eLen);
12584 return FALSE;
12585 }
12586 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
12587 {
12588 /* OUI - 0x00 0X50 0XF2
12589 WPA Information Element - 0x01
12590 WPA version - 0x01*/
12591 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
12592 return TRUE;
12593 }
12594 ie += eLen;
12595 remLen -= eLen;
12596 }
12597 return FALSE;
12598}
12599
12600/*
Jeff Johnson295189b2012-06-20 16:38:30 -070012601 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012602 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012603 * parameters during connect operation.
12604 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012605int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012606 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012607 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012608{
12609 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012610 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012611 ENTER();
12612
12613 /*set wpa version*/
12614 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
12615
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012616 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012617 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053012618 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012619 {
12620 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12621 }
12622 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
12623 {
12624 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12625 }
12626 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012627
12628 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012629 pWextState->wpaVersion);
12630
12631 /*set authentication type*/
12632 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
12633
12634 if (0 > status)
12635 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012636 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012637 "%s: failed to set authentication type ", __func__);
12638 return status;
12639 }
12640
12641 /*set key mgmt type*/
12642 if (req->crypto.n_akm_suites)
12643 {
12644 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
12645 if (0 > status)
12646 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012647 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070012648 __func__);
12649 return status;
12650 }
12651 }
12652
12653 /*set pairwise cipher type*/
12654 if (req->crypto.n_ciphers_pairwise)
12655 {
12656 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
12657 req->crypto.ciphers_pairwise[0], true);
12658 if (0 > status)
12659 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012660 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012661 "%s: failed to set unicast cipher type", __func__);
12662 return status;
12663 }
12664 }
12665 else
12666 {
12667 /*Reset previous cipher suite to none*/
12668 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
12669 if (0 > status)
12670 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012671 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012672 "%s: failed to set unicast cipher type", __func__);
12673 return status;
12674 }
12675 }
12676
12677 /*set group cipher type*/
12678 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
12679 false);
12680
12681 if (0 > status)
12682 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012683 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070012684 __func__);
12685 return status;
12686 }
12687
Chet Lanctot186b5732013-03-18 10:26:30 -070012688#ifdef WLAN_FEATURE_11W
12689 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
12690#endif
12691
Jeff Johnson295189b2012-06-20 16:38:30 -070012692 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
12693 if (req->ie_len)
12694 {
12695 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
12696 if ( 0 > status)
12697 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012698 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012699 __func__);
12700 return status;
12701 }
12702 }
12703
12704 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012705 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012706 {
12707 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
12708 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
12709 )
12710 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012711 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070012712 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
12713 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012714 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012715 __func__);
12716 return -EOPNOTSUPP;
12717 }
12718 else
12719 {
12720 u8 key_len = req->key_len;
12721 u8 key_idx = req->key_idx;
12722
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012723 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012724 && (CSR_MAX_NUM_KEY > key_idx)
12725 )
12726 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012727 hddLog(VOS_TRACE_LEVEL_INFO,
12728 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012729 __func__, key_idx, key_len);
12730 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012731 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012732 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012733 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012734 (u8)key_len;
12735 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
12736 }
12737 }
12738 }
12739 }
12740
12741 return status;
12742}
12743
12744/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012745 * FUNCTION: wlan_hdd_try_disconnect
12746 * This function is used to disconnect from previous
12747 * connection
12748 */
12749static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
12750{
12751 long ret = 0;
12752 hdd_station_ctx_t *pHddStaCtx;
12753 eMib_dot11DesiredBssType connectedBssType;
12754
12755 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12756
12757 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
12758
12759 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
12760 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
12761 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
12762 {
12763 /* Issue disconnect to CSR */
12764 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12765 if( eHAL_STATUS_SUCCESS ==
12766 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12767 pAdapter->sessionId,
12768 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12769 {
12770 ret = wait_for_completion_interruptible_timeout(
12771 &pAdapter->disconnect_comp_var,
12772 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12773 if (0 >= ret)
12774 {
12775 hddLog(LOGE, FL("Failed to receive disconnect event"));
12776 return -EALREADY;
12777 }
12778 }
12779 }
12780 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
12781 {
12782 ret = wait_for_completion_interruptible_timeout(
12783 &pAdapter->disconnect_comp_var,
12784 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12785 if (0 >= ret)
12786 {
12787 hddLog(LOGE, FL("Failed to receive disconnect event"));
12788 return -EALREADY;
12789 }
12790 }
12791
12792 return 0;
12793}
12794
12795/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053012796 * FUNCTION: __wlan_hdd_cfg80211_connect
12797 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012798 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012799static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012800 struct net_device *ndev,
12801 struct cfg80211_connect_params *req
12802 )
12803{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012804 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012805 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012806 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053012807 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012808
12809 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012810
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012811 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12812 TRACE_CODE_HDD_CFG80211_CONNECT,
12813 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012814 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012815 "%s: device_mode = %s (%d)", __func__,
12816 hdd_device_modetoString(pAdapter->device_mode),
12817 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012818
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012819 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012820 if (!pHddCtx)
12821 {
12822 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12823 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053012824 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012825 }
12826
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012827 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012828 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012829 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012830 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012831 }
12832
Agarwal Ashish51325b52014-06-16 16:50:49 +053012833 if (vos_max_concurrent_connections_reached()) {
12834 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12835 return -ECONNREFUSED;
12836 }
12837
Jeff Johnson295189b2012-06-20 16:38:30 -070012838#ifdef WLAN_BTAMP_FEATURE
12839 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012840 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070012841 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012842 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012843 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012844 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070012845 }
12846#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012847
12848 //If Device Mode is Station Concurrent Sessions Exit BMps
12849 //P2P Mode will be taken care in Open/close adapter
12850 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012851 (vos_concurrent_open_sessions_running())) {
12852 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
12853 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012854 }
12855
12856 /*Try disconnecting if already in connected state*/
12857 status = wlan_hdd_try_disconnect(pAdapter);
12858 if ( 0 > status)
12859 {
12860 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12861 " connection"));
12862 return -EALREADY;
12863 }
12864
Jeff Johnson295189b2012-06-20 16:38:30 -070012865 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012866 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070012867
12868 if ( 0 > status)
12869 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012870 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070012871 __func__);
12872 return status;
12873 }
Mohit Khanna765234a2012-09-11 15:08:35 -070012874 if ( req->channel )
12875 {
12876 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
12877 req->ssid_len, req->bssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012878 req->bssid_hint,
Mohit Khanna765234a2012-09-11 15:08:35 -070012879 req->channel->hw_value);
12880 }
12881 else
12882 {
12883 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012884 req->ssid_len, req->bssid,
12885 req->bssid_hint, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070012886 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012887
Sushant Kaushikd7083982015-03-18 14:33:24 +053012888 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012889 {
12890 //ReEnable BMPS if disabled
12891 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
12892 (NULL != pHddCtx))
12893 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012894 if (pHddCtx->hdd_wlan_suspended)
12895 {
12896 hdd_set_pwrparams(pHddCtx);
12897 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012898 //ReEnable Bmps and Imps back
12899 hdd_enable_bmps_imps(pHddCtx);
12900 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053012901 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070012902 return status;
12903 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012904 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012905 EXIT();
12906 return status;
12907}
12908
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012909static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
12910 struct net_device *ndev,
12911 struct cfg80211_connect_params *req)
12912{
12913 int ret;
12914 vos_ssr_protect(__func__);
12915 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
12916 vos_ssr_unprotect(__func__);
12917
12918 return ret;
12919}
Jeff Johnson295189b2012-06-20 16:38:30 -070012920
12921/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012922 * FUNCTION: wlan_hdd_disconnect
12923 * This function is used to issue a disconnect request to SME
12924 */
12925int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
12926{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012927 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012928 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012929 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012930 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012931
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012932 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012933
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012934 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012935 if (0 != status)
12936 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012937 return status;
12938 }
12939
Sushant Kaushikb4834d22015-07-15 15:29:05 +053012940 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
12941 {
12942 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
12943 pAdapter->sessionId);
12944 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012945 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012946
Agarwal Ashish47d18112014-08-04 19:55:07 +053012947 /* Need to apply spin lock before decreasing active sessions
12948 * as there can be chance for double decrement if context switch
12949 * Calls hdd_DisConnectHandler.
12950 */
12951
12952 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012953 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
12954 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012955 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
12956 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053012957 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
12958 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012959
Abhishek Singhf4669da2014-05-26 15:07:49 +053012960 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053012961 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
12962
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012963 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012964
Mihir Shete182a0b22014-08-18 16:08:48 +053012965 /*
12966 * stop tx queues before deleting STA/BSS context from the firmware.
12967 * tx has to be disabled because the firmware can get busy dropping
12968 * the tx frames after BSS/STA has been deleted and will not send
12969 * back a response resulting in WDI timeout
12970 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053012971 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053012972 netif_tx_disable(pAdapter->dev);
12973 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012974
Mihir Shete182a0b22014-08-18 16:08:48 +053012975 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012976 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12977 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012978 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
12979 {
12980 hddLog(VOS_TRACE_LEVEL_INFO,
12981 FL("status = %d, already disconnected"),
12982 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012983
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012984 }
12985 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012986 {
12987 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012988 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012989 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012990 result = -EINVAL;
12991 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012992 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012993 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012994 &pAdapter->disconnect_comp_var,
12995 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012996 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012997 {
12998 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012999 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013000 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013001 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013002 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013003 {
13004 hddLog(VOS_TRACE_LEVEL_ERROR,
13005 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013006 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013007 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013008disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13010 FL("Set HDD connState to eConnectionState_NotConnected"));
13011 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
13012
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013013 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013014 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013015}
13016
13017
13018/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013019 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070013020 * This function is used to issue a disconnect request to SME
13021 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013022static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013023 struct net_device *dev,
13024 u16 reason
13025 )
13026{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013027 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013028 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013029 tCsrRoamProfile *pRoamProfile;
13030 hdd_station_ctx_t *pHddStaCtx;
13031 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013032#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013033 tANI_U8 staIdx;
13034#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013035
Jeff Johnson295189b2012-06-20 16:38:30 -070013036 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013037
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013038 if (!pAdapter) {
13039 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
13040 return -EINVAL;
13041 }
13042
13043 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13044 if (!pHddStaCtx) {
13045 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
13046 return -EINVAL;
13047 }
13048
13049 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13050 status = wlan_hdd_validate_context(pHddCtx);
13051 if (0 != status)
13052 {
13053 return status;
13054 }
13055
13056 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
13057
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013058 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13059 TRACE_CODE_HDD_CFG80211_DISCONNECT,
13060 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013061 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
13062 __func__, hdd_device_modetoString(pAdapter->device_mode),
13063 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013064
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013065 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
13066 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070013067
Jeff Johnson295189b2012-06-20 16:38:30 -070013068 if (NULL != pRoamProfile)
13069 {
13070 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053013071 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
13072 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070013073 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013074 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070013075 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013076 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013077 switch(reason)
13078 {
13079 case WLAN_REASON_MIC_FAILURE:
13080 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
13081 break;
13082
13083 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
13084 case WLAN_REASON_DISASSOC_AP_BUSY:
13085 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
13086 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
13087 break;
13088
13089 case WLAN_REASON_PREV_AUTH_NOT_VALID:
13090 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053013091 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070013092 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
13093 break;
13094
Jeff Johnson295189b2012-06-20 16:38:30 -070013095 default:
13096 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
13097 break;
13098 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013099 pScanInfo = &pHddCtx->scan_info;
13100 if (pScanInfo->mScanPending)
13101 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053013102 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013103 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013104 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053013105 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013106 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053013107 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013108#ifdef FEATURE_WLAN_TDLS
13109 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013110 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013111 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013112 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
13113 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013114 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013115 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013116 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053013117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013118 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013119 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013120 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053013121 status = sme_DeleteTdlsPeerSta(
13122 WLAN_HDD_GET_HAL_CTX(pAdapter),
13123 pAdapter->sessionId,
13124 mac);
13125 if (status != eHAL_STATUS_SUCCESS) {
13126 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
13127 return -EPERM;
13128 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013129 }
13130 }
13131#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013132 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013133 status = wlan_hdd_disconnect(pAdapter, reasonCode);
13134 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070013135 {
13136 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013137 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013138 __func__, (int)status );
13139 return -EINVAL;
13140 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013141 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053013142 else
13143 {
13144 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
13145 "called while in %d state", __func__,
13146 pHddStaCtx->conn_info.connState);
13147 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013148 }
13149 else
13150 {
13151 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
13152 }
13153
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013154 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013155 return status;
13156}
13157
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013158static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
13159 struct net_device *dev,
13160 u16 reason
13161 )
13162{
13163 int ret;
13164 vos_ssr_protect(__func__);
13165 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
13166 vos_ssr_unprotect(__func__);
13167
13168 return ret;
13169}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013170
Jeff Johnson295189b2012-06-20 16:38:30 -070013171/*
13172 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013173 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070013174 * settings in IBSS mode.
13175 */
13176static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013177 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013178 struct cfg80211_ibss_params *params
13179 )
13180{
13181 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013182 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013183 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13184 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013185
Jeff Johnson295189b2012-06-20 16:38:30 -070013186 ENTER();
13187
13188 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070013189 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070013190
13191 if (params->ie_len && ( NULL != params->ie) )
13192 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013193 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13194 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013195 {
13196 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
13197 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13198 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013199 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013200 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013201 tDot11fIEWPA dot11WPAIE;
13202 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013203 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013204
Wilson Yang00256342013-10-10 23:13:38 -070013205 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013206 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13207 params->ie_len, DOT11F_EID_WPA);
13208 if ( NULL != ie )
13209 {
13210 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
13211 // Unpack the WPA IE
13212 //Skip past the EID byte and length byte - and four byte WiFi OUI
13213 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
13214 &ie[2+4],
13215 ie[1] - 4,
13216 &dot11WPAIE);
13217 /*Extract the multicast cipher, the encType for unicast
13218 cipher for wpa-none is none*/
13219 encryptionType =
13220 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
13221 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013222 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013223
Jeff Johnson295189b2012-06-20 16:38:30 -070013224 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
13225
13226 if (0 > status)
13227 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013228 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070013229 __func__);
13230 return status;
13231 }
13232 }
13233
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013234 pWextState->roamProfile.AuthType.authType[0] =
13235 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013236 eCSR_AUTH_TYPE_OPEN_SYSTEM;
13237
13238 if (params->privacy)
13239 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013240 /* Security enabled IBSS, At this time there is no information available
13241 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070013242 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013243 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070013244 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013245 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070013246 *enable privacy bit in beacons */
13247
13248 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13249 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013250 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
13251 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070013252 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13253 pWextState->roamProfile.EncryptionType.numEntries = 1;
13254 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070013255 return status;
13256}
13257
13258/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013259 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013260 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013261 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013262static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013263 struct net_device *dev,
13264 struct cfg80211_ibss_params *params
13265 )
13266{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013267 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013268 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13269 tCsrRoamProfile *pRoamProfile;
13270 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013271 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13272 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013273 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070013274
13275 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013276
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013277 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13278 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
13279 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013280 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013281 "%s: device_mode = %s (%d)", __func__,
13282 hdd_device_modetoString(pAdapter->device_mode),
13283 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013284
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013285 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013286 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013287 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013288 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013289 }
13290
13291 if (NULL == pWextState)
13292 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013293 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070013294 __func__);
13295 return -EIO;
13296 }
13297
Agarwal Ashish51325b52014-06-16 16:50:49 +053013298 if (vos_max_concurrent_connections_reached()) {
13299 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13300 return -ECONNREFUSED;
13301 }
13302
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013303 /*Try disconnecting if already in connected state*/
13304 status = wlan_hdd_try_disconnect(pAdapter);
13305 if ( 0 > status)
13306 {
13307 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
13308 " IBSS connection"));
13309 return -EALREADY;
13310 }
13311
Jeff Johnson295189b2012-06-20 16:38:30 -070013312 pRoamProfile = &pWextState->roamProfile;
13313
13314 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
13315 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013316 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013317 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013318 return -EINVAL;
13319 }
13320
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013321 /* BSSID is provided by upper layers hence no need to AUTO generate */
13322 if (NULL != params->bssid) {
13323 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
13324 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
13325 hddLog (VOS_TRACE_LEVEL_ERROR,
13326 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
13327 return -EIO;
13328 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013329 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013330 }
krunal sonie9002db2013-11-25 14:24:17 -080013331 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
13332 {
13333 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
13334 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
13335 {
13336 hddLog (VOS_TRACE_LEVEL_ERROR,
13337 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
13338 return -EIO;
13339 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013340
13341 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080013342 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013343 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080013344 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013345
Jeff Johnson295189b2012-06-20 16:38:30 -070013346 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070013347 if (NULL !=
13348#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13349 params->chandef.chan)
13350#else
13351 params->channel)
13352#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013353 {
13354 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013355 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13356 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
13357 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13358 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013359
13360 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013361 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070013362 ieee80211_frequency_to_channel(
13363#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13364 params->chandef.chan->center_freq);
13365#else
13366 params->channel->center_freq);
13367#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013368
13369 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13370 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070013371 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013372 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
13373 __func__);
13374 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070013375 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013376
13377 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013378 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013379 if (channelNum == validChan[indx])
13380 {
13381 break;
13382 }
13383 }
13384 if (indx >= numChans)
13385 {
13386 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013387 __func__, channelNum);
13388 return -EINVAL;
13389 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013390 /* Set the Operational Channel */
13391 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
13392 channelNum);
13393 pRoamProfile->ChannelInfo.numOfChannels = 1;
13394 pHddStaCtx->conn_info.operationChannel = channelNum;
13395 pRoamProfile->ChannelInfo.ChannelList =
13396 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070013397 }
13398
13399 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013400 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070013401 if (status < 0)
13402 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013403 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070013404 __func__);
13405 return status;
13406 }
13407
13408 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013409 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013410 params->ssid_len, params->bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013411 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013412
13413 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013414 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013415
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013416 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013417 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013418}
13419
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013420static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
13421 struct net_device *dev,
13422 struct cfg80211_ibss_params *params
13423 )
13424{
13425 int ret = 0;
13426
13427 vos_ssr_protect(__func__);
13428 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
13429 vos_ssr_unprotect(__func__);
13430
13431 return ret;
13432}
13433
Jeff Johnson295189b2012-06-20 16:38:30 -070013434/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013435 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013436 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013437 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013438static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013439 struct net_device *dev
13440 )
13441{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013442 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013443 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13444 tCsrRoamProfile *pRoamProfile;
13445 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013446 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013447
13448 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013449
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013450 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13451 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
13452 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013453 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013454 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013455 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013456 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013457 }
13458
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013459 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
13460 hdd_device_modetoString(pAdapter->device_mode),
13461 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013462 if (NULL == pWextState)
13463 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013464 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070013465 __func__);
13466 return -EIO;
13467 }
13468
13469 pRoamProfile = &pWextState->roamProfile;
13470
13471 /* Issue disconnect only if interface type is set to IBSS */
13472 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
13473 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013474 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070013475 __func__);
13476 return -EINVAL;
13477 }
13478
13479 /* Issue Disconnect request */
13480 INIT_COMPLETION(pAdapter->disconnect_comp_var);
13481 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13482 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
13483
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013484 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013485 return 0;
13486}
13487
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013488static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
13489 struct net_device *dev
13490 )
13491{
13492 int ret = 0;
13493
13494 vos_ssr_protect(__func__);
13495 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
13496 vos_ssr_unprotect(__func__);
13497
13498 return ret;
13499}
13500
Jeff Johnson295189b2012-06-20 16:38:30 -070013501/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013502 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070013503 * This function is used to set the phy parameters
13504 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
13505 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013506static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013507 u32 changed)
13508{
13509 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13510 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013511 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013512
13513 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013514
13515 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013516 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
13517 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013518
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013519 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013520 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013521 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013522 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013523 }
13524
Jeff Johnson295189b2012-06-20 16:38:30 -070013525 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
13526 {
13527 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
13528 WNI_CFG_RTS_THRESHOLD_STAMAX :
13529 wiphy->rts_threshold;
13530
13531 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013532 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070013533 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013534 hddLog(VOS_TRACE_LEVEL_ERROR,
13535 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013536 __func__, rts_threshold);
13537 return -EINVAL;
13538 }
13539
13540 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
13541 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013542 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013543 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013544 hddLog(VOS_TRACE_LEVEL_ERROR,
13545 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013546 __func__, rts_threshold);
13547 return -EIO;
13548 }
13549
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013550 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013551 rts_threshold);
13552 }
13553
13554 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
13555 {
13556 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
13557 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
13558 wiphy->frag_threshold;
13559
13560 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013561 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013562 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013563 hddLog(VOS_TRACE_LEVEL_ERROR,
13564 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013565 frag_threshold);
13566 return -EINVAL;
13567 }
13568
13569 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
13570 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013571 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013572 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013573 hddLog(VOS_TRACE_LEVEL_ERROR,
13574 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013575 __func__, frag_threshold);
13576 return -EIO;
13577 }
13578
13579 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
13580 frag_threshold);
13581 }
13582
13583 if ((changed & WIPHY_PARAM_RETRY_SHORT)
13584 || (changed & WIPHY_PARAM_RETRY_LONG))
13585 {
13586 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
13587 wiphy->retry_short :
13588 wiphy->retry_long;
13589
13590 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
13591 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
13592 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013593 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013594 __func__, retry_value);
13595 return -EINVAL;
13596 }
13597
13598 if (changed & WIPHY_PARAM_RETRY_SHORT)
13599 {
13600 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
13601 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013602 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013603 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013604 hddLog(VOS_TRACE_LEVEL_ERROR,
13605 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013606 __func__, retry_value);
13607 return -EIO;
13608 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013609 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013610 __func__, retry_value);
13611 }
13612 else if (changed & WIPHY_PARAM_RETRY_SHORT)
13613 {
13614 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
13615 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013616 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013617 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013618 hddLog(VOS_TRACE_LEVEL_ERROR,
13619 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013620 __func__, retry_value);
13621 return -EIO;
13622 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013623 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013624 __func__, retry_value);
13625 }
13626 }
13627
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013628 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013629 return 0;
13630}
13631
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013632static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
13633 u32 changed)
13634{
13635 int ret;
13636
13637 vos_ssr_protect(__func__);
13638 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
13639 vos_ssr_unprotect(__func__);
13640
13641 return ret;
13642}
13643
Jeff Johnson295189b2012-06-20 16:38:30 -070013644/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013645 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013646 * This function is used to set the txpower
13647 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013648static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013649#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13650 struct wireless_dev *wdev,
13651#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013652#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013653 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013654#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013655 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013656#endif
13657 int dbm)
13658{
13659 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013660 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013661 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13662 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013663 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013664
13665 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013666
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013667 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13668 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
13669 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013670 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013671 if (0 != status)
13672 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013673 return status;
13674 }
13675
13676 hHal = pHddCtx->hHal;
13677
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013678 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
13679 dbm, ccmCfgSetCallback,
13680 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013681 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013682 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013683 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
13684 return -EIO;
13685 }
13686
13687 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
13688 dbm);
13689
13690 switch(type)
13691 {
13692 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
13693 /* Fall through */
13694 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
13695 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
13696 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013697 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
13698 __func__);
13699 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013700 }
13701 break;
13702 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013703 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070013704 __func__);
13705 return -EOPNOTSUPP;
13706 break;
13707 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013708 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
13709 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070013710 return -EIO;
13711 }
13712
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013713 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013714 return 0;
13715}
13716
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013717static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
13718#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13719 struct wireless_dev *wdev,
13720#endif
13721#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13722 enum tx_power_setting type,
13723#else
13724 enum nl80211_tx_power_setting type,
13725#endif
13726 int dbm)
13727{
13728 int ret;
13729 vos_ssr_protect(__func__);
13730 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
13731#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13732 wdev,
13733#endif
13734#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13735 type,
13736#else
13737 type,
13738#endif
13739 dbm);
13740 vos_ssr_unprotect(__func__);
13741
13742 return ret;
13743}
13744
Jeff Johnson295189b2012-06-20 16:38:30 -070013745/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013746 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013747 * This function is used to read the txpower
13748 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013749static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013750#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13751 struct wireless_dev *wdev,
13752#endif
13753 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070013754{
13755
13756 hdd_adapter_t *pAdapter;
13757 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013758 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013759
Jeff Johnsone7245742012-09-05 17:12:55 -070013760 ENTER();
13761
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013762 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013763 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013764 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013765 *dbm = 0;
13766 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013767 }
13768
Jeff Johnson295189b2012-06-20 16:38:30 -070013769 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
13770 if (NULL == pAdapter)
13771 {
13772 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
13773 return -ENOENT;
13774 }
13775
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053013776 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13777 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
13778 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013779 wlan_hdd_get_classAstats(pAdapter);
13780 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
13781
Jeff Johnsone7245742012-09-05 17:12:55 -070013782 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013783 return 0;
13784}
13785
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013786static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
13787#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13788 struct wireless_dev *wdev,
13789#endif
13790 int *dbm)
13791{
13792 int ret;
13793
13794 vos_ssr_protect(__func__);
13795 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
13796#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13797 wdev,
13798#endif
13799 dbm);
13800 vos_ssr_unprotect(__func__);
13801
13802 return ret;
13803}
13804
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013805static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013806#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13807 const u8* mac,
13808#else
13809 u8* mac,
13810#endif
13811 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070013812{
13813 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13814 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13815 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053013816 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013817
13818 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
13819 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070013820
13821 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
13822 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
13823 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
13824 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
13825 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
13826 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
13827 tANI_U16 maxRate = 0;
13828 tANI_U16 myRate;
13829 tANI_U16 currentRate = 0;
13830 tANI_U8 maxSpeedMCS = 0;
13831 tANI_U8 maxMCSIdx = 0;
13832 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053013833 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013834 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013835 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013836
Leo Chang6f8870f2013-03-26 18:11:36 -070013837#ifdef WLAN_FEATURE_11AC
13838 tANI_U32 vht_mcs_map;
13839 eDataRate11ACMaxMcs vhtMaxMcs;
13840#endif /* WLAN_FEATURE_11AC */
13841
Jeff Johnsone7245742012-09-05 17:12:55 -070013842 ENTER();
13843
Jeff Johnson295189b2012-06-20 16:38:30 -070013844 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
13845 (0 == ssidlen))
13846 {
13847 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
13848 " Invalid ssidlen, %d", __func__, ssidlen);
13849 /*To keep GUI happy*/
13850 return 0;
13851 }
13852
Mukul Sharma811205f2014-07-09 21:07:30 +053013853 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
13854 {
13855 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13856 "%s: Roaming in progress, so unable to proceed this request", __func__);
13857 return 0;
13858 }
13859
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013860 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013861 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013862 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013863 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013864 }
13865
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053013866 wlan_hdd_get_station_stats(pAdapter);
13867 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013868
Kiet Lam3b17fc82013-09-27 05:24:08 +053013869 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
13870 sinfo->filled |= STATION_INFO_SIGNAL;
13871
c_hpothu09f19542014-05-30 21:53:31 +053013872 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053013873 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
13874 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053013875 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053013876 {
13877 rate_flags = pAdapter->maxRateFlags;
13878 }
c_hpothu44ff4e02014-05-08 00:13:57 +053013879
Jeff Johnson295189b2012-06-20 16:38:30 -070013880 //convert to the UI units of 100kbps
13881 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
13882
13883#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070013884 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 -070013885 sinfo->signal,
13886 pCfg->reportMaxLinkSpeed,
13887 myRate,
13888 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013889 (int) pCfg->linkSpeedRssiMid,
13890 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070013891 (int) rate_flags,
13892 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013893#endif //LINKSPEED_DEBUG_ENABLED
13894
13895 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
13896 {
13897 // we do not want to necessarily report the current speed
13898 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
13899 {
13900 // report the max possible speed
13901 rssidx = 0;
13902 }
13903 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
13904 {
13905 // report the max possible speed with RSSI scaling
13906 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
13907 {
13908 // report the max possible speed
13909 rssidx = 0;
13910 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013911 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070013912 {
13913 // report middle speed
13914 rssidx = 1;
13915 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013916 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
13917 {
13918 // report middle speed
13919 rssidx = 2;
13920 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013921 else
13922 {
13923 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013924 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070013925 }
13926 }
13927 else
13928 {
13929 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
13930 hddLog(VOS_TRACE_LEVEL_ERROR,
13931 "%s: Invalid value for reportMaxLinkSpeed: %u",
13932 __func__, pCfg->reportMaxLinkSpeed);
13933 rssidx = 0;
13934 }
13935
13936 maxRate = 0;
13937
13938 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013939 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
13940 OperationalRates, &ORLeng))
13941 {
13942 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13943 /*To keep GUI happy*/
13944 return 0;
13945 }
13946
Jeff Johnson295189b2012-06-20 16:38:30 -070013947 for (i = 0; i < ORLeng; i++)
13948 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013949 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013950 {
13951 /* Validate Rate Set */
13952 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
13953 {
13954 currentRate = supported_data_rate[j].supported_rate[rssidx];
13955 break;
13956 }
13957 }
13958 /* Update MAX rate */
13959 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13960 }
13961
13962 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013963 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
13964 ExtendedRates, &ERLeng))
13965 {
13966 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13967 /*To keep GUI happy*/
13968 return 0;
13969 }
13970
Jeff Johnson295189b2012-06-20 16:38:30 -070013971 for (i = 0; i < ERLeng; i++)
13972 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013973 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013974 {
13975 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
13976 {
13977 currentRate = supported_data_rate[j].supported_rate[rssidx];
13978 break;
13979 }
13980 }
13981 /* Update MAX rate */
13982 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13983 }
c_hpothu79aab322014-07-14 21:11:01 +053013984
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013985 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053013986 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013987 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053013988 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070013989 {
c_hpothu79aab322014-07-14 21:11:01 +053013990 if (rate_flags & eHAL_TX_RATE_VHT80)
13991 mode = 2;
13992 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
13993 mode = 1;
13994 else
13995 mode = 0;
13996
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013997 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
13998 MCSRates, &MCSLeng))
13999 {
14000 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14001 /*To keep GUI happy*/
14002 return 0;
14003 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014004 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070014005#ifdef WLAN_FEATURE_11AC
14006 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014007 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070014008 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014009 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014010 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070014011 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070014012 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014013 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070014014 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014015 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070014016 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014017 maxMCSIdx = 7;
14018 }
14019 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
14020 {
14021 maxMCSIdx = 8;
14022 }
14023 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
14024 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014025 //VHT20 is supporting 0~8
14026 if (rate_flags & eHAL_TX_RATE_VHT20)
14027 maxMCSIdx = 8;
14028 else
14029 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070014030 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014031
c_hpothu79aab322014-07-14 21:11:01 +053014032 if (0 != rssidx)/*check for scaled */
14033 {
14034 //get middle rate MCS index if rssi=1/2
14035 for (i=0; i <= maxMCSIdx; i++)
14036 {
14037 if (sinfo->signal <= rssiMcsTbl[mode][i])
14038 {
14039 maxMCSIdx = i;
14040 break;
14041 }
14042 }
14043 }
14044
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014045 if (rate_flags & eHAL_TX_RATE_VHT80)
14046 {
14047 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
14048 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
14049 }
14050 else if (rate_flags & eHAL_TX_RATE_VHT40)
14051 {
14052 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
14053 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
14054 }
14055 else if (rate_flags & eHAL_TX_RATE_VHT20)
14056 {
14057 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
14058 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
14059 }
14060
Leo Chang6f8870f2013-03-26 18:11:36 -070014061 maxSpeedMCS = 1;
14062 if (currentRate > maxRate)
14063 {
14064 maxRate = currentRate;
14065 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014066
Leo Chang6f8870f2013-03-26 18:11:36 -070014067 }
14068 else
14069#endif /* WLAN_FEATURE_11AC */
14070 {
14071 if (rate_flags & eHAL_TX_RATE_HT40)
14072 {
14073 rateFlag |= 1;
14074 }
14075 if (rate_flags & eHAL_TX_RATE_SGI)
14076 {
14077 rateFlag |= 2;
14078 }
14079
Girish Gowli01abcee2014-07-31 20:18:55 +053014080 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053014081 if (rssidx == 1 || rssidx == 2)
14082 {
14083 //get middle rate MCS index if rssi=1/2
14084 for (i=0; i <= 7; i++)
14085 {
14086 if (sinfo->signal <= rssiMcsTbl[mode][i])
14087 {
14088 temp = i+1;
14089 break;
14090 }
14091 }
14092 }
c_hpothu79aab322014-07-14 21:11:01 +053014093
14094 for (i = 0; i < MCSLeng; i++)
14095 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014096 for (j = 0; j < temp; j++)
14097 {
14098 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
14099 {
14100 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053014101 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070014102 break;
14103 }
14104 }
14105 if ((j < temp) && (currentRate > maxRate))
14106 {
14107 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070014108 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014109 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053014110 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070014111 }
14112 }
14113
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014114 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
14115 {
14116 maxRate = myRate;
14117 maxSpeedMCS = 1;
14118 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
14119 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014120 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053014121 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070014122 {
14123 maxRate = myRate;
14124 if (rate_flags & eHAL_TX_RATE_LEGACY)
14125 {
14126 maxSpeedMCS = 0;
14127 }
14128 else
14129 {
14130 maxSpeedMCS = 1;
14131 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
14132 }
14133 }
14134
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014135 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070014136 {
14137 sinfo->txrate.legacy = maxRate;
14138#ifdef LINKSPEED_DEBUG_ENABLED
14139 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
14140#endif //LINKSPEED_DEBUG_ENABLED
14141 }
14142 else
14143 {
14144 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070014145#ifdef WLAN_FEATURE_11AC
14146 sinfo->txrate.nss = 1;
14147 if (rate_flags & eHAL_TX_RATE_VHT80)
14148 {
14149 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014150 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070014151 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014152 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070014153 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014154 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14155 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14156 }
14157 else if (rate_flags & eHAL_TX_RATE_VHT20)
14158 {
14159 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14160 }
14161#endif /* WLAN_FEATURE_11AC */
14162 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
14163 {
14164 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14165 if (rate_flags & eHAL_TX_RATE_HT40)
14166 {
14167 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14168 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014169 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014170 if (rate_flags & eHAL_TX_RATE_SGI)
14171 {
14172 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14173 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014174
Jeff Johnson295189b2012-06-20 16:38:30 -070014175#ifdef LINKSPEED_DEBUG_ENABLED
14176 pr_info("Reporting MCS rate %d flags %x\n",
14177 sinfo->txrate.mcs,
14178 sinfo->txrate.flags );
14179#endif //LINKSPEED_DEBUG_ENABLED
14180 }
14181 }
14182 else
14183 {
14184 // report current rate instead of max rate
14185
14186 if (rate_flags & eHAL_TX_RATE_LEGACY)
14187 {
14188 //provide to the UI in units of 100kbps
14189 sinfo->txrate.legacy = myRate;
14190#ifdef LINKSPEED_DEBUG_ENABLED
14191 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
14192#endif //LINKSPEED_DEBUG_ENABLED
14193 }
14194 else
14195 {
14196 //must be MCS
14197 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070014198#ifdef WLAN_FEATURE_11AC
14199 sinfo->txrate.nss = 1;
14200 if (rate_flags & eHAL_TX_RATE_VHT80)
14201 {
14202 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14203 }
14204 else
14205#endif /* WLAN_FEATURE_11AC */
14206 {
14207 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14208 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014209 if (rate_flags & eHAL_TX_RATE_SGI)
14210 {
14211 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14212 }
14213 if (rate_flags & eHAL_TX_RATE_HT40)
14214 {
14215 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14216 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014217#ifdef WLAN_FEATURE_11AC
14218 else if (rate_flags & eHAL_TX_RATE_VHT80)
14219 {
14220 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
14221 }
14222#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070014223#ifdef LINKSPEED_DEBUG_ENABLED
14224 pr_info("Reporting actual MCS rate %d flags %x\n",
14225 sinfo->txrate.mcs,
14226 sinfo->txrate.flags );
14227#endif //LINKSPEED_DEBUG_ENABLED
14228 }
14229 }
14230 sinfo->filled |= STATION_INFO_TX_BITRATE;
14231
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014232 sinfo->tx_packets =
14233 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
14234 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
14235 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
14236 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
14237
14238 sinfo->tx_retries =
14239 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
14240 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
14241 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
14242 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
14243
14244 sinfo->tx_failed =
14245 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
14246 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
14247 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
14248 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
14249
14250 sinfo->filled |=
14251 STATION_INFO_TX_PACKETS |
14252 STATION_INFO_TX_RETRIES |
14253 STATION_INFO_TX_FAILED;
14254
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014255 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14256 TRACE_CODE_HDD_CFG80211_GET_STA,
14257 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014258 EXIT();
14259 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014260}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014261#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14262static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14263 const u8* mac, struct station_info *sinfo)
14264#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014265static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14266 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014267#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014268{
14269 int ret;
14270
14271 vos_ssr_protect(__func__);
14272 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
14273 vos_ssr_unprotect(__func__);
14274
14275 return ret;
14276}
14277
14278static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070014279 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070014280{
14281 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014282 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014283 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014284 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014285
Jeff Johnsone7245742012-09-05 17:12:55 -070014286 ENTER();
14287
Jeff Johnson295189b2012-06-20 16:38:30 -070014288 if (NULL == pAdapter)
14289 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014290 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014291 return -ENODEV;
14292 }
14293
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014294 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14295 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
14296 pAdapter->sessionId, timeout));
14297
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014298 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014299 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014300 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014301 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014302 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014303 }
14304
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014305 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
14306 (TRUE == pHddCtx->hdd_wlan_suspended) &&
14307 (pHddCtx->cfg_ini->fhostArpOffload) &&
14308 (eConnectionState_Associated ==
14309 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14310 {
Amar Singhald53568e2013-09-26 11:03:45 -070014311
14312 hddLog(VOS_TRACE_LEVEL_INFO,
14313 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053014314 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014315 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14316 {
14317 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014318 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014319 __func__, vos_status);
14320 }
14321 }
14322
Jeff Johnson295189b2012-06-20 16:38:30 -070014323 /**The get power cmd from the supplicant gets updated by the nl only
14324 *on successful execution of the function call
14325 *we are oppositely mapped w.r.t mode in the driver
14326 **/
14327 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
14328
14329 if (VOS_STATUS_E_FAILURE == vos_status)
14330 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014331 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14332 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014333 return -EINVAL;
14334 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014335 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014336 return 0;
14337}
14338
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014339static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
14340 struct net_device *dev, bool mode, int timeout)
14341{
14342 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014343
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014344 vos_ssr_protect(__func__);
14345 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
14346 vos_ssr_unprotect(__func__);
14347
14348 return ret;
14349}
Sushant Kaushik084f6592015-09-10 13:11:56 +053014350static const struct
14351nla_policy
14352qca_wlan_vendor_get_wifi_info_policy[
14353 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
14354 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
14355 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
14356};
14357
14358/**
14359 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
14360 * @wiphy: pointer to wireless wiphy structure.
14361 * @wdev: pointer to wireless_dev structure.
14362 * @data: Pointer to the data to be passed via vendor interface
14363 * @data_len:Length of the data to be passed
14364 *
14365 * This is called when wlan driver needs to send wifi driver related info
14366 * (driver/fw version) to the user space application upon request.
14367 *
14368 * Return: Return the Success or Failure code.
14369 */
14370static int
14371wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
14372 struct wireless_dev *wdev,
14373 const void *data, int data_len)
14374{
14375 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
14376 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
14377 tSirVersionString version;
14378 uint32 version_len;
14379 uint8 attr;
14380 int status;
14381 struct sk_buff *reply_skb = NULL;
14382
14383 if (VOS_FTM_MODE == hdd_get_conparam()) {
14384 hddLog(LOGE, FL("Command not allowed in FTM mode"));
14385 return -EINVAL;
14386 }
14387
14388 status = wlan_hdd_validate_context(hdd_ctx);
14389 if (0 != status) {
14390 hddLog(LOGE, FL("HDD context is not valid"));
14391 return -EINVAL;
14392 }
14393
14394 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
14395 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
14396 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
14397 return -EINVAL;
14398 }
14399
14400 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
14401 hddLog(LOG1, FL("Rcvd req for Driver version "
14402 "Driver version is %s"),QWLAN_VERSIONSTR);
14403 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
14404 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
14405 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
14406 hddLog(LOG1, FL("Rcvd req for FW version "
14407 "FW version is %s"), hdd_ctx->fw_Version);
14408 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
14409 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
14410 } else {
14411 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
14412 return -EINVAL;
14413 }
14414
14415 version_len = strlen(version);
14416 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
14417 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
14418 if (!reply_skb) {
14419 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
14420 return -ENOMEM;
14421 }
14422
14423 if (nla_put(reply_skb, attr, version_len, version)) {
14424 hddLog(LOGE, FL("nla put fail"));
14425 kfree_skb(reply_skb);
14426 return -EINVAL;
14427 }
14428
14429 return cfg80211_vendor_cmd_reply(reply_skb);
14430}
14431
Jeff Johnson295189b2012-06-20 16:38:30 -070014432#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014433static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
14434 struct net_device *netdev,
14435 u8 key_index)
14436{
14437 ENTER();
14438 return 0;
14439}
14440
Jeff Johnson295189b2012-06-20 16:38:30 -070014441static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014442 struct net_device *netdev,
14443 u8 key_index)
14444{
14445 int ret;
14446 vos_ssr_protect(__func__);
14447 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
14448 vos_ssr_unprotect(__func__);
14449 return ret;
14450}
14451#endif //LINUX_VERSION_CODE
14452
14453#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14454static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14455 struct net_device *dev,
14456 struct ieee80211_txq_params *params)
14457{
14458 ENTER();
14459 return 0;
14460}
14461#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14462static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14463 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014464{
Jeff Johnsone7245742012-09-05 17:12:55 -070014465 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070014466 return 0;
14467}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014468#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070014469
14470#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14471static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014472 struct net_device *dev,
14473 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014474{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014475 int ret;
14476
14477 vos_ssr_protect(__func__);
14478 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
14479 vos_ssr_unprotect(__func__);
14480 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014481}
14482#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14483static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
14484 struct ieee80211_txq_params *params)
14485{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014486 int ret;
14487
14488 vos_ssr_protect(__func__);
14489 ret = __wlan_hdd_set_txq_params(wiphy, params);
14490 vos_ssr_unprotect(__func__);
14491 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014492}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014493#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014494
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014495static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014496 struct net_device *dev,
14497 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070014498{
14499 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014500 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014501 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014502 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014503 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014504 v_CONTEXT_t pVosContext = NULL;
14505 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014506
Jeff Johnsone7245742012-09-05 17:12:55 -070014507 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014508
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014509 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070014510 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014511 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014512 return -EINVAL;
14513 }
14514
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014515 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14516 TRACE_CODE_HDD_CFG80211_DEL_STA,
14517 pAdapter->sessionId, pAdapter->device_mode));
14518
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014519 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14520 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014521 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014522 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014523 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014524 }
14525
Jeff Johnson295189b2012-06-20 16:38:30 -070014526 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014527 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014528 )
14529 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014530 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14531 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14532 if(pSapCtx == NULL){
14533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14534 FL("psapCtx is NULL"));
14535 return -ENOENT;
14536 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014537 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070014538 {
14539 v_U16_t i;
14540 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
14541 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014542 if ((pSapCtx->aStaInfo[i].isUsed) &&
14543 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070014544 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014545 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014546 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014547 ETHER_ADDR_LEN);
14548
Jeff Johnson295189b2012-06-20 16:38:30 -070014549 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014550 "%s: Delete STA with MAC::"
14551 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014552 __func__,
14553 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
14554 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070014555 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014556 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014557 }
14558 }
14559 }
14560 else
14561 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014562
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014563 vos_status = hdd_softap_GetStaId(pAdapter,
14564 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014565 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14566 {
14567 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014568 "%s: Skip this DEL STA as this is not used::"
14569 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014570 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014571 return -ENOENT;
14572 }
14573
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014574 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014575 {
14576 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014577 "%s: Skip this DEL STA as deauth is in progress::"
14578 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014579 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014580 return -ENOENT;
14581 }
14582
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014583 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014584
Jeff Johnson295189b2012-06-20 16:38:30 -070014585 hddLog(VOS_TRACE_LEVEL_INFO,
14586 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014587 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014588 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014589 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014590
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014591 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014592 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14593 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014594 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014595 hddLog(VOS_TRACE_LEVEL_INFO,
14596 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014597 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014598 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014599 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014600 return -ENOENT;
14601 }
14602
Jeff Johnson295189b2012-06-20 16:38:30 -070014603 }
14604 }
14605
14606 EXIT();
14607
14608 return 0;
14609}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014610
14611#ifdef CFG80211_DEL_STA_V2
14612static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14613 struct net_device *dev,
14614 struct station_del_parameters *param)
14615#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014616#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14617static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14618 struct net_device *dev, const u8 *mac)
14619#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014620static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14621 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014622#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014623#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014624{
14625 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014626 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070014627
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014628 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014629
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014630#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014631 if (NULL == param) {
14632 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014633 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014634 return -EINVAL;
14635 }
14636
14637 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
14638 param->subtype, &delStaParams);
14639
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014640#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014641 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014642 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014643#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014644 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
14645
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014646 vos_ssr_unprotect(__func__);
14647
14648 return ret;
14649}
14650
14651static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014652 struct net_device *dev,
14653#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14654 const u8 *mac,
14655#else
14656 u8 *mac,
14657#endif
14658 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014659{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014660 hdd_adapter_t *pAdapter;
14661 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014662 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014663#ifdef FEATURE_WLAN_TDLS
14664 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014665
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014666 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014667
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014668 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14669 if (NULL == pAdapter)
14670 {
14671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14672 "%s: Adapter is NULL",__func__);
14673 return -EINVAL;
14674 }
14675 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14676 status = wlan_hdd_validate_context(pHddCtx);
14677 if (0 != status)
14678 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014679 return status;
14680 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014681
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014682 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14683 TRACE_CODE_HDD_CFG80211_ADD_STA,
14684 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014685 mask = params->sta_flags_mask;
14686
14687 set = params->sta_flags_set;
14688
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014689 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014690 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
14691 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014692
14693 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
14694 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014695 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014696 }
14697 }
14698#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014699 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014700 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014701}
14702
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014703#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14704static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14705 struct net_device *dev, const u8 *mac,
14706 struct station_parameters *params)
14707#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014708static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14709 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014710#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014711{
14712 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014713
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014714 vos_ssr_protect(__func__);
14715 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
14716 vos_ssr_unprotect(__func__);
14717
14718 return ret;
14719}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014720#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070014721
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014722static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070014723 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014724{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014725 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14726 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014727 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014728 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014729 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014730 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070014731
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014732 ENTER();
14733
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014734 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014735 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014736 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014737 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014738 return -EINVAL;
14739 }
14740
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014741 if (!pmksa) {
14742 hddLog(LOGE, FL("pmksa is NULL"));
14743 return -EINVAL;
14744 }
14745
14746 if (!pmksa->bssid || !pmksa->pmkid) {
14747 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
14748 pmksa->bssid, pmksa->pmkid);
14749 return -EINVAL;
14750 }
14751
14752 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
14753 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14754
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014755 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14756 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014757 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014758 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014759 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014760 }
14761
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014762 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014763 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14764
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014765 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
14766 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014767
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014768 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014769 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014770 &pmk_id, 1, FALSE);
14771
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014772 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14773 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
14774 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014775
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014776 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014777 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014778}
14779
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014780static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
14781 struct cfg80211_pmksa *pmksa)
14782{
14783 int ret;
14784
14785 vos_ssr_protect(__func__);
14786 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
14787 vos_ssr_unprotect(__func__);
14788
14789 return ret;
14790}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014791
Wilson Yang6507c4e2013-10-01 20:11:19 -070014792
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014793static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070014794 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014795{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014796 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14797 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014798 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014799 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014800
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014801 ENTER();
14802
Wilson Yang6507c4e2013-10-01 20:11:19 -070014803 /* Validate pAdapter */
14804 if (NULL == pAdapter)
14805 {
14806 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
14807 return -EINVAL;
14808 }
14809
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014810 if (!pmksa) {
14811 hddLog(LOGE, FL("pmksa is NULL"));
14812 return -EINVAL;
14813 }
14814
14815 if (!pmksa->bssid) {
14816 hddLog(LOGE, FL("pmksa->bssid is NULL"));
14817 return -EINVAL;
14818 }
14819
Kiet Lam98c46a12014-10-31 15:34:57 -070014820 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
14821 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14822
Wilson Yang6507c4e2013-10-01 20:11:19 -070014823 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14824 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014825 if (0 != status)
14826 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014827 return status;
14828 }
14829
14830 /*Retrieve halHandle*/
14831 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14832
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014833 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14834 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
14835 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014836 /* Delete the PMKID CSR cache */
14837 if (eHAL_STATUS_SUCCESS !=
14838 sme_RoamDelPMKIDfromCache(halHandle,
14839 pAdapter->sessionId, pmksa->bssid, FALSE)) {
14840 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
14841 MAC_ADDR_ARRAY(pmksa->bssid));
14842 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014843 }
14844
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014845 EXIT();
14846 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014847}
14848
Wilson Yang6507c4e2013-10-01 20:11:19 -070014849
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014850static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
14851 struct cfg80211_pmksa *pmksa)
14852{
14853 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014854
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014855 vos_ssr_protect(__func__);
14856 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
14857 vos_ssr_unprotect(__func__);
14858
14859 return ret;
14860
14861}
14862
14863static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014864{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014865 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14866 tHalHandle halHandle;
14867 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014868 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014869
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014870 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070014871
14872 /* Validate pAdapter */
14873 if (NULL == pAdapter)
14874 {
14875 hddLog(VOS_TRACE_LEVEL_ERROR,
14876 "%s: Invalid Adapter" ,__func__);
14877 return -EINVAL;
14878 }
14879
14880 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14881 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014882 if (0 != status)
14883 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014884 return status;
14885 }
14886
14887 /*Retrieve halHandle*/
14888 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14889
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014890 /* Flush the PMKID cache in CSR */
14891 if (eHAL_STATUS_SUCCESS !=
14892 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
14893 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
14894 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014895 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014896 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080014897 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014898}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014899
14900static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
14901{
14902 int ret;
14903
14904 vos_ssr_protect(__func__);
14905 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
14906 vos_ssr_unprotect(__func__);
14907
14908 return ret;
14909}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014910#endif
14911
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014912#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014913static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14914 struct net_device *dev,
14915 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014916{
14917 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14918 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014919 hdd_context_t *pHddCtx;
14920 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014921
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014922 ENTER();
14923
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014924 if (NULL == pAdapter)
14925 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014926 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014927 return -ENODEV;
14928 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014929 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14930 ret = wlan_hdd_validate_context(pHddCtx);
14931 if (0 != ret)
14932 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014933 return ret;
14934 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014935 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014936 if (NULL == pHddStaCtx)
14937 {
14938 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
14939 return -EINVAL;
14940 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014941
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014942 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14943 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
14944 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014945 // Added for debug on reception of Re-assoc Req.
14946 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
14947 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014948 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014949 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080014950 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014951 }
14952
14953#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080014954 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014955 ftie->ie_len);
14956#endif
14957
14958 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014959 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
14960 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014961 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014962
14963 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014964 return 0;
14965}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014966
14967static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14968 struct net_device *dev,
14969 struct cfg80211_update_ft_ies_params *ftie)
14970{
14971 int ret;
14972
14973 vos_ssr_protect(__func__);
14974 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
14975 vos_ssr_unprotect(__func__);
14976
14977 return ret;
14978}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014979#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014980
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014981#ifdef FEATURE_WLAN_SCAN_PNO
14982
14983void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
14984 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
14985{
14986 int ret;
14987 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
14988 hdd_context_t *pHddCtx;
14989
Nirav Shah80830bf2013-12-31 16:35:12 +053014990 ENTER();
14991
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014992 if (NULL == pAdapter)
14993 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014994 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014995 "%s: HDD adapter is Null", __func__);
14996 return ;
14997 }
14998
14999 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15000 if (NULL == pHddCtx)
15001 {
15002 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15003 "%s: HDD context is Null!!!", __func__);
15004 return ;
15005 }
15006
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015007 spin_lock(&pHddCtx->schedScan_lock);
15008 if (TRUE == pHddCtx->isWiphySuspended)
15009 {
15010 pHddCtx->isSchedScanUpdatePending = TRUE;
15011 spin_unlock(&pHddCtx->schedScan_lock);
15012 hddLog(VOS_TRACE_LEVEL_INFO,
15013 "%s: Update cfg80211 scan database after it resume", __func__);
15014 return ;
15015 }
15016 spin_unlock(&pHddCtx->schedScan_lock);
15017
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015018 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
15019
15020 if (0 > ret)
15021 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
15022
15023 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15025 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015026}
15027
15028/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015029 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015030 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015031 */
15032static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
15033{
15034 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15035 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015036 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015037 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15038 int status = 0;
15039 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
15040
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015041 /* The current firmware design does not allow PNO during any
15042 * active sessions. Hence, determine the active sessions
15043 * and return a failure.
15044 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015045 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
15046 {
15047 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015048 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015049
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015050 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
15051 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
15052 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
15053 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
15054 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053015055 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015056 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015057 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015058 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015059 }
15060 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15061 pAdapterNode = pNext;
15062 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015063 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015064}
15065
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015066void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
15067{
15068 hdd_adapter_t *pAdapter = callbackContext;
15069 hdd_context_t *pHddCtx;
15070
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015071 ENTER();
15072
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015073 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
15074 {
15075 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15076 FL("Invalid adapter or adapter has invalid magic"));
15077 return;
15078 }
15079
15080 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15081 if (0 != wlan_hdd_validate_context(pHddCtx))
15082 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015083 return;
15084 }
15085
c_hpothub53c45d2014-08-18 16:53:14 +053015086 if (VOS_STATUS_SUCCESS != status)
15087 {
15088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015089 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053015090 pHddCtx->isPnoEnable = FALSE;
15091 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015092
15093 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
15094 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015095 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015096}
15097
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015098/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015099 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
15100 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015101 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015102static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015103 struct net_device *dev, struct cfg80211_sched_scan_request *request)
15104{
15105 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015106 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015107 hdd_context_t *pHddCtx;
15108 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015109 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053015110 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
15111 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015112 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15113 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015114 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015115 hdd_config_t *pConfig = NULL;
15116 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015117
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015118 ENTER();
15119
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015120 if (NULL == pAdapter)
15121 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015123 "%s: HDD adapter is Null", __func__);
15124 return -ENODEV;
15125 }
15126
15127 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015128 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015129
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015130 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015131 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015132 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015133 }
15134
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015135 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015136 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15137 if (NULL == hHal)
15138 {
15139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15140 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015141 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015142 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015143 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15144 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
15145 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053015146 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015147 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053015148 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015149 {
15150 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15151 "%s: aborting the existing scan is unsuccessfull", __func__);
15152 return -EBUSY;
15153 }
15154
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015155 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015156 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015157 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015158 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015159 return -EBUSY;
15160 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015161
c_hpothu37f21312014-04-09 21:49:54 +053015162 if (TRUE == pHddCtx->isPnoEnable)
15163 {
15164 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15165 FL("already PNO is enabled"));
15166 return -EBUSY;
15167 }
c_hpothu225aa7c2014-10-22 17:45:13 +053015168
15169 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
15170 {
15171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15172 "%s: abort ROC failed ", __func__);
15173 return -EBUSY;
15174 }
15175
c_hpothu37f21312014-04-09 21:49:54 +053015176 pHddCtx->isPnoEnable = TRUE;
15177
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015178 pnoRequest.enable = 1; /*Enable PNO */
15179 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015180
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015181 if (( !pnoRequest.ucNetworksCount ) ||
15182 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015183 {
15184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015185 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015186 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015187 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015188 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015189 goto error;
15190 }
15191
15192 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
15193 {
15194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015195 "%s: Incorrect number of channels %d",
15196 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015197 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015198 goto error;
15199 }
15200
15201 /* Framework provides one set of channels(all)
15202 * common for all saved profile */
15203 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15204 channels_allowed, &num_channels_allowed))
15205 {
15206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15207 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015208 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015209 goto error;
15210 }
15211 /* Checking each channel against allowed channel list */
15212 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053015213 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015214 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015215 char chList [(request->n_channels*5)+1];
15216 int len;
15217 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015218 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015219 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015220 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015221 if (request->channels[i]->hw_value == channels_allowed[indx])
15222 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015223 if ((!pConfig->enableDFSPnoChnlScan) &&
15224 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
15225 {
15226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15227 "%s : Dropping DFS channel : %d",
15228 __func__,channels_allowed[indx]);
15229 num_ignore_dfs_ch++;
15230 break;
15231 }
15232
Nirav Shah80830bf2013-12-31 16:35:12 +053015233 valid_ch[num_ch++] = request->channels[i]->hw_value;
15234 len += snprintf(chList+len, 5, "%d ",
15235 request->channels[i]->hw_value);
15236 break ;
15237 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015238 }
15239 }
Nirav Shah80830bf2013-12-31 16:35:12 +053015240 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015241
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015242 /*If all channels are DFS and dropped, then ignore the PNO request*/
15243 if (num_ignore_dfs_ch == request->n_channels)
15244 {
15245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15246 "%s : All requested channels are DFS channels", __func__);
15247 ret = -EINVAL;
15248 goto error;
15249 }
15250 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015251
15252 pnoRequest.aNetworks =
15253 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15254 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015255 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015256 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15257 FL("failed to allocate memory aNetworks %u"),
15258 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15259 goto error;
15260 }
15261 vos_mem_zero(pnoRequest.aNetworks,
15262 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15263
15264 /* Filling per profile params */
15265 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
15266 {
15267 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015268 request->match_sets[i].ssid.ssid_len;
15269
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015270 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
15271 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015272 {
15273 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015274 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015275 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015276 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015277 goto error;
15278 }
15279
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015280 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015281 request->match_sets[i].ssid.ssid,
15282 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15284 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015285 i, pnoRequest.aNetworks[i].ssId.ssId);
15286 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
15287 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
15288 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015289
15290 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015291 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
15292 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015293
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015294 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015295 }
15296
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015297 for (i = 0; i < request->n_ssids; i++)
15298 {
15299 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015300 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015301 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015302 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015303 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015304 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015305 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015306 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015307 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015308 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015309 break;
15310 }
15311 j++;
15312 }
15313 }
15314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15315 "Number of hidden networks being Configured = %d",
15316 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015317 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080015318 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015319
15320 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15321 if (pnoRequest.p24GProbeTemplate == NULL)
15322 {
15323 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15324 FL("failed to allocate memory p24GProbeTemplate %u"),
15325 SIR_PNO_MAX_PB_REQ_SIZE);
15326 goto error;
15327 }
15328
15329 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15330 if (pnoRequest.p5GProbeTemplate == NULL)
15331 {
15332 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15333 FL("failed to allocate memory p5GProbeTemplate %u"),
15334 SIR_PNO_MAX_PB_REQ_SIZE);
15335 goto error;
15336 }
15337
15338 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15339 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15340
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053015341 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
15342 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015343 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015344 pnoRequest.us24GProbeTemplateLen = request->ie_len;
15345 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
15346 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015347
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015348 pnoRequest.us5GProbeTemplateLen = request->ie_len;
15349 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
15350 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015351 }
15352
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015353 /* Driver gets only one time interval which is hardcoded in
15354 * supplicant for 10000ms. Taking power consumption into account 6 timers
15355 * will be used, Timervalue is increased exponentially i.e 10,20,40,
15356 * 80,160,320 secs. And number of scan cycle for each timer
15357 * is configurable through INI param gPNOScanTimerRepeatValue.
15358 * If it is set to 0 only one timer will be used and PNO scan cycle
15359 * will be repeated after each interval specified by supplicant
15360 * till PNO is disabled.
15361 */
15362 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015363 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015364 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015365 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015366 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
15367
15368 tempInterval = (request->interval)/1000;
15369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15370 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
15371 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015372 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015373 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015374 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015375 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015376 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015377 tempInterval *= 2;
15378 }
15379 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015380 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015381
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015382 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015383
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015384 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015385 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
15386 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015387 pAdapter->pno_req_status = 0;
15388
Nirav Shah80830bf2013-12-31 16:35:12 +053015389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15390 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015391 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
15392 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053015393
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015394 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015395 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015396 hdd_cfg80211_sched_scan_done_callback, pAdapter);
15397 if (eHAL_STATUS_SUCCESS != status)
15398 {
15399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015400 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015401 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015402 goto error;
15403 }
15404
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015405 ret = wait_for_completion_timeout(
15406 &pAdapter->pno_comp_var,
15407 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
15408 if (0 >= ret)
15409 {
15410 // Did not receive the response for PNO enable in time.
15411 // Assuming the PNO enable was success.
15412 // Returning error from here, because we timeout, results
15413 // in side effect of Wifi (Wifi Setting) not to work.
15414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15415 FL("Timed out waiting for PNO to be Enabled"));
15416 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015417 }
15418
15419 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053015420 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015421
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015422error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15424 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053015425 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015426 if (pnoRequest.aNetworks)
15427 vos_mem_free(pnoRequest.aNetworks);
15428 if (pnoRequest.p24GProbeTemplate)
15429 vos_mem_free(pnoRequest.p24GProbeTemplate);
15430 if (pnoRequest.p5GProbeTemplate)
15431 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015432
15433 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015434 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015435}
15436
15437/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015438 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
15439 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015440 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015441static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
15442 struct net_device *dev, struct cfg80211_sched_scan_request *request)
15443{
15444 int ret;
15445
15446 vos_ssr_protect(__func__);
15447 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
15448 vos_ssr_unprotect(__func__);
15449
15450 return ret;
15451}
15452
15453/*
15454 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
15455 * Function to disable PNO
15456 */
15457static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015458 struct net_device *dev)
15459{
15460 eHalStatus status = eHAL_STATUS_FAILURE;
15461 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15462 hdd_context_t *pHddCtx;
15463 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015464 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015465 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015466
15467 ENTER();
15468
15469 if (NULL == pAdapter)
15470 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015472 "%s: HDD adapter is Null", __func__);
15473 return -ENODEV;
15474 }
15475
15476 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015477
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015478 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015479 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015481 "%s: HDD context is Null", __func__);
15482 return -ENODEV;
15483 }
15484
15485 /* The return 0 is intentional when isLogpInProgress and
15486 * isLoadUnloadInProgress. We did observe a crash due to a return of
15487 * failure in sched_scan_stop , especially for a case where the unload
15488 * of the happens at the same time. The function __cfg80211_stop_sched_scan
15489 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
15490 * success. If it returns a failure , then its next invocation due to the
15491 * clean up of the second interface will have the dev pointer corresponding
15492 * to the first one leading to a crash.
15493 */
15494 if (pHddCtx->isLogpInProgress)
15495 {
15496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15497 "%s: LOGP in Progress. Ignore!!!", __func__);
15498 return ret;
15499 }
15500
Mihir Shete18156292014-03-11 15:38:30 +053015501 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015502 {
15503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15504 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15505 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015506 }
15507
15508 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15509 if (NULL == hHal)
15510 {
15511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15512 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015513 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015514 }
15515
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015516 pnoRequest.enable = 0; /* Disable PNO */
15517 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015518
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015519 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15520 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
15521 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015522 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015523 pAdapter->sessionId,
15524 NULL, pAdapter);
15525 if (eHAL_STATUS_SUCCESS != status)
15526 {
15527 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15528 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015529 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015530 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015531 }
c_hpothu37f21312014-04-09 21:49:54 +053015532 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015533
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015534error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015536 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015537
15538 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015539 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015540}
15541
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015542/*
15543 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
15544 * NL interface to disable PNO
15545 */
15546static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
15547 struct net_device *dev)
15548{
15549 int ret;
15550
15551 vos_ssr_protect(__func__);
15552 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
15553 vos_ssr_unprotect(__func__);
15554
15555 return ret;
15556}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015557#endif /*FEATURE_WLAN_SCAN_PNO*/
15558
15559
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015560#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015561#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015562static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15563 struct net_device *dev,
15564 u8 *peer, u8 action_code,
15565 u8 dialog_token,
15566 u16 status_code, u32 peer_capability,
15567 const u8 *buf, size_t len)
15568#else /* TDLS_MGMT_VERSION2 */
15569#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
15570static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15571 struct net_device *dev,
15572 const u8 *peer, u8 action_code,
15573 u8 dialog_token, u16 status_code,
15574 u32 peer_capability, bool initiator,
15575 const u8 *buf, size_t len)
15576#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
15577static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15578 struct net_device *dev,
15579 const u8 *peer, u8 action_code,
15580 u8 dialog_token, u16 status_code,
15581 u32 peer_capability, const u8 *buf,
15582 size_t len)
15583#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
15584static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15585 struct net_device *dev,
15586 u8 *peer, u8 action_code,
15587 u8 dialog_token,
15588 u16 status_code, u32 peer_capability,
15589 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015590#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015591static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15592 struct net_device *dev,
15593 u8 *peer, u8 action_code,
15594 u8 dialog_token,
15595 u16 status_code, const u8 *buf,
15596 size_t len)
15597#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015598#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015599{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015600 hdd_adapter_t *pAdapter;
15601 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015602 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070015603 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080015604 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070015605 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015606 int ret;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015607#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015608 u32 peer_capability = 0;
15609#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015610 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015611 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015612
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015613 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15614 if (NULL == pAdapter)
15615 {
15616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15617 "%s: Adapter is NULL",__func__);
15618 return -EINVAL;
15619 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015620 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15621 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
15622 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015623
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015624 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015625 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015626 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015628 "Invalid arguments");
15629 return -EINVAL;
15630 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015631
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015632 if (pHddCtx->isLogpInProgress)
15633 {
15634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15635 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053015636 wlan_hdd_tdls_set_link_status(pAdapter,
15637 peer,
15638 eTDLS_LINK_IDLE,
15639 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015640 return -EBUSY;
15641 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015642
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015643 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
15644 {
15645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15646 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15647 return -EAGAIN;
15648 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015649
Hoonki Lee27511902013-03-14 18:19:06 -070015650 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015651 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015653 "%s: TDLS mode is disabled OR not enabled in FW."
15654 MAC_ADDRESS_STR " action %d declined.",
15655 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015656 return -ENOTSUPP;
15657 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015658
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015659 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15660
15661 if( NULL == pHddStaCtx )
15662 {
15663 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15664 "%s: HDD station context NULL ",__func__);
15665 return -EINVAL;
15666 }
15667
15668 /* STA should be connected and authenticated
15669 * before sending any TDLS frames
15670 */
15671 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15672 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
15673 {
15674 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15675 "STA is not connected or unauthenticated. "
15676 "connState %u, uIsAuthenticated %u",
15677 pHddStaCtx->conn_info.connState,
15678 pHddStaCtx->conn_info.uIsAuthenticated);
15679 return -EAGAIN;
15680 }
15681
Hoonki Lee27511902013-03-14 18:19:06 -070015682 /* other than teardown frame, other mgmt frames are not sent if disabled */
15683 if (SIR_MAC_TDLS_TEARDOWN != action_code)
15684 {
15685 /* if tdls_mode is disabled to respond to peer's request */
15686 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
15687 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015688 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015689 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015690 " TDLS mode is disabled. action %d declined.",
15691 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070015692
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015693 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070015694 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053015695
15696 if (vos_max_concurrent_connections_reached())
15697 {
15698 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15699 return -EINVAL;
15700 }
Hoonki Lee27511902013-03-14 18:19:06 -070015701 }
15702
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015703 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
15704 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053015705 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015706 {
15707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015708 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015709 " TDLS setup is ongoing. action %d declined.",
15710 __func__, MAC_ADDR_ARRAY(peer), action_code);
15711 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015712 }
15713 }
15714
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015715 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
15716 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080015717 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015718 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15719 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015720 {
15721 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
15722 we return error code at 'add_station()'. Hence we have this
15723 check again in addtion to add_station().
15724 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015725 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015726 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15728 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015729 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
15730 __func__, MAC_ADDR_ARRAY(peer), action_code,
15731 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053015732 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080015733 }
15734 else
15735 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015736 /* maximum reached. tweak to send error code to peer and return
15737 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015738 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15740 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015741 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
15742 __func__, MAC_ADDR_ARRAY(peer), status_code,
15743 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070015744 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015745 /* fall through to send setup resp with failure status
15746 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015747 }
15748 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015749 else
15750 {
15751 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053015752 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015753 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015754 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015756 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
15757 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015758 return -EPERM;
15759 }
15760 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015761 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015762
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015764 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015765 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
15766 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015767
Hoonki Leea34dd892013-02-05 22:56:02 -080015768 /*Except teardown responder will not be used so just make 0*/
15769 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015770 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080015771 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015772
15773 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015774 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015775
15776 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
15777 responder = pTdlsPeer->is_responder;
15778 else
Hoonki Leea34dd892013-02-05 22:56:02 -080015779 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015781 "%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 -070015782 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
15783 dialog_token, status_code, len);
15784 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080015785 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015786 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015787
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015788 /* For explicit trigger of DIS_REQ come out of BMPS for
15789 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070015790 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015791 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
15792 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070015793 {
15794 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
15795 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015797 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015798 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
15799 if (status != VOS_STATUS_SUCCESS) {
15800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
15801 }
Hoonki Lee14621352013-04-16 17:51:19 -070015802 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015803 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015804 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015805 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
15806 }
15807 }
Hoonki Lee14621352013-04-16 17:51:19 -070015808 }
15809
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015810 /* make sure doesn't call send_mgmt() while it is pending */
15811 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
15812 {
15813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015814 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015815 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015816 ret = -EBUSY;
15817 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015818 }
15819
15820 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015821 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
15822
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015823 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
15824 pAdapter->sessionId, peer, action_code, dialog_token,
15825 status_code, peer_capability, (tANI_U8 *)buf, len,
15826 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015827
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015828 if (VOS_STATUS_SUCCESS != status)
15829 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015830 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15831 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015832 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015833 ret = -EINVAL;
15834 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015835 }
15836
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015837 if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
15838 (SIR_MAC_TDLS_DIS_RSP == action_code))
15839 {
15840 /* for DIS_REQ/DIS_RSP, supplicant don't consider the return status.
15841 * So we no need to wait for tdls_mgmt_comp for sending ack status.
15842 */
15843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15844 "%s: tx done for frm %u", __func__, action_code);
15845 return 0;
15846 }
15847
15848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15849 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
15850 WAIT_TIME_TDLS_MGMT);
15851
Hoonki Leed37cbb32013-04-20 00:31:14 -070015852 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
15853 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
15854
15855 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015856 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070015857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015858 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070015859 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015860 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080015861
15862 if (pHddCtx->isLogpInProgress)
15863 {
15864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15865 "%s: LOGP in Progress. Ignore!!!", __func__);
15866 return -EAGAIN;
15867 }
15868
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015869 ret = -EINVAL;
15870 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015871 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015872 else
15873 {
15874 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15875 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
15876 __func__, rc, pAdapter->mgmtTxCompletionStatus);
15877 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015878
Gopichand Nakkala05922802013-03-14 12:23:19 -070015879 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070015880 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015881 ret = max_sta_failed;
15882 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070015883 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015884
Hoonki Leea34dd892013-02-05 22:56:02 -080015885 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
15886 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015887 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15889 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015890 }
15891 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
15892 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015893 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015894 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15895 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015896 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015897
15898 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015899
15900tx_failed:
15901 /* add_station will be called before sending TDLS_SETUP_REQ and
15902 * TDLS_SETUP_RSP and as part of add_station driver will enable
15903 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
15904 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
15905 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
15906 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
15907 */
15908
15909 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
15910 (SIR_MAC_TDLS_SETUP_RSP == action_code))
15911 wlan_hdd_tdls_check_bmps(pAdapter);
15912 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015913}
15914
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015915#if TDLS_MGMT_VERSION2
15916static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15917 u8 *peer, u8 action_code, u8 dialog_token,
15918 u16 status_code, u32 peer_capability,
15919 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015920#else /* TDLS_MGMT_VERSION2 */
15921#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
15922static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15923 struct net_device *dev,
15924 const u8 *peer, u8 action_code,
15925 u8 dialog_token, u16 status_code,
15926 u32 peer_capability, bool initiator,
15927 const u8 *buf, size_t len)
15928#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15929static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15930 struct net_device *dev,
15931 const u8 *peer, u8 action_code,
15932 u8 dialog_token, u16 status_code,
15933 u32 peer_capability, const u8 *buf,
15934 size_t len)
15935#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
15936static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15937 struct net_device *dev,
15938 u8 *peer, u8 action_code,
15939 u8 dialog_token,
15940 u16 status_code, u32 peer_capability,
15941 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015942#else
15943static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15944 u8 *peer, u8 action_code, u8 dialog_token,
15945 u16 status_code, const u8 *buf, size_t len)
15946#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015947#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015948{
15949 int ret;
15950
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015951 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015952#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015953 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15954 dialog_token, status_code,
15955 peer_capability, buf, len);
15956#else /* TDLS_MGMT_VERSION2 */
15957#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
15958 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15959 dialog_token, status_code,
15960 peer_capability, initiator,
15961 buf, len);
15962#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
15963 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15964 dialog_token, status_code,
15965 peer_capability, buf, len);
15966#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
15967 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15968 dialog_token, status_code,
15969 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015970#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015971 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15972 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015973#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015974#endif
15975 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015976
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015977 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015978}
Atul Mittal115287b2014-07-08 13:26:33 +053015979
15980int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015981#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15982 const u8 *peer,
15983#else
Atul Mittal115287b2014-07-08 13:26:33 +053015984 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015985#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015986 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053015987 cfg80211_exttdls_callback callback)
15988{
15989
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015990 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053015991 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015992 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053015993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15994 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
15995 __func__, MAC_ADDR_ARRAY(peer));
15996
15997 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15998 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15999
16000 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016001 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
16002 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
16003 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053016004 return -ENOTSUPP;
16005 }
16006
16007 /* To cater the requirement of establishing the TDLS link
16008 * irrespective of the data traffic , get an entry of TDLS peer.
16009 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016010 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016011 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
16012 if (pTdlsPeer == NULL) {
16013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16014 "%s: peer " MAC_ADDRESS_STR " not existing",
16015 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016016 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016017 return -EINVAL;
16018 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016019 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016020
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053016021 /* check FW TDLS Off Channel capability */
16022 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053016023 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053016024 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016025 {
16026 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
16027 pTdlsPeer->peerParams.global_operating_class =
16028 tdls_peer_params->global_operating_class;
16029 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
16030 pTdlsPeer->peerParams.min_bandwidth_kbps =
16031 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016032 /* check configured channel is valid, non dfs and
16033 * not current operating channel */
16034 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
16035 tdls_peer_params->channel)) &&
16036 (pHddStaCtx) &&
16037 (tdls_peer_params->channel !=
16038 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016039 {
16040 pTdlsPeer->isOffChannelConfigured = TRUE;
16041 }
16042 else
16043 {
16044 pTdlsPeer->isOffChannelConfigured = FALSE;
16045 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16046 "%s: Configured Tdls Off Channel is not valid", __func__);
16047
16048 }
16049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016050 "%s: tdls_off_channel %d isOffChannelConfigured %d "
16051 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016052 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016053 pTdlsPeer->isOffChannelConfigured,
16054 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016055 }
16056 else
16057 {
16058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053016059 "%s: TDLS off channel FW capability %d, "
16060 "host capab %d or Invalid TDLS Peer Params", __func__,
16061 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
16062 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016063 }
16064
Atul Mittal115287b2014-07-08 13:26:33 +053016065 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
16066
16067 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16068 " %s TDLS Add Force Peer Failed",
16069 __func__);
16070 return -EINVAL;
16071 }
16072 /*EXT TDLS*/
16073
16074 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
16075 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16076 " %s TDLS set callback Failed",
16077 __func__);
16078 return -EINVAL;
16079 }
16080
16081 return(0);
16082
16083}
16084
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016085int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
16086#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16087 const u8 *peer
16088#else
16089 u8 *peer
16090#endif
16091)
Atul Mittal115287b2014-07-08 13:26:33 +053016092{
16093
16094 hddTdlsPeer_t *pTdlsPeer;
16095 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16097 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
16098 __func__, MAC_ADDR_ARRAY(peer));
16099
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016100 if (0 != wlan_hdd_validate_context(pHddCtx)) {
16101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
16102 return -EINVAL;
16103 }
16104
Atul Mittal115287b2014-07-08 13:26:33 +053016105 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
16106 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
16107
16108 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016109 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
16110 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
16111 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053016112 return -ENOTSUPP;
16113 }
16114
16115
16116 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
16117
16118 if ( NULL == pTdlsPeer ) {
16119 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016120 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053016121 __func__, MAC_ADDR_ARRAY(peer));
16122 return -EINVAL;
16123 }
16124 else {
16125 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
16126 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016127 /* if channel switch is configured, reset
16128 the channel for this peer */
16129 if (TRUE == pTdlsPeer->isOffChannelConfigured)
16130 {
16131 pTdlsPeer->peerParams.channel = 0;
16132 pTdlsPeer->isOffChannelConfigured = FALSE;
16133 }
Atul Mittal115287b2014-07-08 13:26:33 +053016134 }
16135
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016136 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
16137 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053016138 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016139 }
Atul Mittal115287b2014-07-08 13:26:33 +053016140
16141 /*EXT TDLS*/
16142
16143 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
16144
16145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16146 " %s TDLS set callback Failed",
16147 __func__);
16148 return -EINVAL;
16149 }
16150 return(0);
16151
16152}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016153static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016154#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16155 const u8 *peer,
16156#else
16157 u8 *peer,
16158#endif
16159 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016160{
16161 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16162 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016163 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016164 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016165
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016166 ENTER();
16167
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016168 if (!pAdapter) {
16169 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16170 return -EINVAL;
16171 }
16172
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016173 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16174 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
16175 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016176 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016177 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070016179 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016180 return -EINVAL;
16181 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016182
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016183 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016184 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016185 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016186 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016187 }
16188
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016189
16190 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016191 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016192 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016194 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
16195 "Cannot process TDLS commands",
16196 pHddCtx->cfg_ini->fEnableTDLSSupport,
16197 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016198 return -ENOTSUPP;
16199 }
16200
16201 switch (oper) {
16202 case NL80211_TDLS_ENABLE_LINK:
16203 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016204 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016205 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016206 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053016207 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016208 tANI_U16 numCurrTdlsPeers = 0;
16209 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016210 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016211
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16213 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
16214 __func__, MAC_ADDR_ARRAY(peer));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016215 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016216 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016217 if ( NULL == pTdlsPeer ) {
16218 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16219 " (oper %d) not exsting. ignored",
16220 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16221 return -EINVAL;
16222 }
16223
16224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16225 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16226 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16227 "NL80211_TDLS_ENABLE_LINK");
16228
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070016229 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
16230 {
16231 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
16232 MAC_ADDRESS_STR " failed",
16233 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
16234 return -EINVAL;
16235 }
16236
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016237 /* before starting tdls connection, set tdls
16238 * off channel established status to default value */
16239 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016240 /* TDLS Off Channel, Disable tdls channel switch,
16241 when there are more than one tdls link */
16242 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053016243 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016244 {
16245 /* get connected peer and send disable tdls off chan */
16246 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016247 if ((connPeer) &&
16248 (connPeer->isOffChannelSupported == TRUE) &&
16249 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016250 {
16251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16252 "%s: More then one peer connected, Disable "
16253 "TDLS channel switch", __func__);
16254
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016255 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016256 ret = sme_SendTdlsChanSwitchReq(
16257 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016258 pAdapter->sessionId,
16259 connPeer->peerMac,
16260 connPeer->peerParams.channel,
16261 TDLS_OFF_CHANNEL_BW_OFFSET,
16262 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016263 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016264 hddLog(VOS_TRACE_LEVEL_ERROR,
16265 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016266 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016267 }
16268 else
16269 {
16270 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16271 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016272 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016273 "isOffChannelConfigured %d",
16274 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016275 (connPeer ? (connPeer->isOffChannelSupported)
16276 : -1),
16277 (connPeer ? (connPeer->isOffChannelConfigured)
16278 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016279 }
16280 }
16281
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016282 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016283 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016284 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053016285
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016286 if (0 != wlan_hdd_tdls_get_link_establish_params(
16287 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016288 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016289 return -EINVAL;
16290 }
16291 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016292
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016293 ret = sme_SendTdlsLinkEstablishParams(
16294 WLAN_HDD_GET_HAL_CTX(pAdapter),
16295 pAdapter->sessionId, peer,
16296 &tdlsLinkEstablishParams);
16297 if (ret != VOS_STATUS_SUCCESS) {
16298 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
16299 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016300 /* Send TDLS peer UAPSD capabilities to the firmware and
16301 * register with the TL on after the response for this operation
16302 * is received .
16303 */
16304 ret = wait_for_completion_interruptible_timeout(
16305 &pAdapter->tdls_link_establish_req_comp,
16306 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
16307 if (ret <= 0)
16308 {
16309 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016310 FL("Link Establish Request Failed Status %ld"),
16311 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016312 return -EINVAL;
16313 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016314 }
Atul Mittal115287b2014-07-08 13:26:33 +053016315 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16316 eTDLS_LINK_CONNECTED,
16317 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016318 staDesc.ucSTAId = pTdlsPeer->staId;
16319 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016320 ret = WLANTL_UpdateTdlsSTAClient(
16321 pHddCtx->pvosContext,
16322 &staDesc);
16323 if (ret != VOS_STATUS_SUCCESS) {
16324 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
16325 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053016326
Gopichand Nakkala471708b2013-06-04 20:03:01 +053016327 /* Mark TDLS client Authenticated .*/
16328 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
16329 pTdlsPeer->staId,
16330 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016331 if (VOS_STATUS_SUCCESS == status)
16332 {
Hoonki Lee14621352013-04-16 17:51:19 -070016333 if (pTdlsPeer->is_responder == 0)
16334 {
16335 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053016336 tdlsConnInfo_t *tdlsInfo;
16337
16338 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
16339
16340 /* Initialize initiator wait callback */
16341 vos_timer_init(
16342 &pTdlsPeer->initiatorWaitTimeoutTimer,
16343 VOS_TIMER_TYPE_SW,
16344 wlan_hdd_tdls_initiator_wait_cb,
16345 tdlsInfo);
Hoonki Lee14621352013-04-16 17:51:19 -070016346
16347 wlan_hdd_tdls_timer_restart(pAdapter,
16348 &pTdlsPeer->initiatorWaitTimeoutTimer,
16349 WAIT_TIME_TDLS_INITIATOR);
16350 /* suspend initiator TX until it receives direct packet from the
16351 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016352 ret = WLANTL_SuspendDataTx(
16353 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16354 &staId, NULL);
16355 if (ret != VOS_STATUS_SUCCESS) {
16356 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
16357 }
Hoonki Lee14621352013-04-16 17:51:19 -070016358 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016359
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016360 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016361 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016362 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016363 suppChannelLen =
16364 tdlsLinkEstablishParams.supportedChannelsLen;
16365
16366 if ((suppChannelLen > 0) &&
16367 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
16368 {
16369 tANI_U8 suppPeerChannel = 0;
16370 int i = 0;
16371 for (i = 0U; i < suppChannelLen; i++)
16372 {
16373 suppPeerChannel =
16374 tdlsLinkEstablishParams.supportedChannels[i];
16375
16376 pTdlsPeer->isOffChannelSupported = FALSE;
16377 if (suppPeerChannel ==
16378 pTdlsPeer->peerParams.channel)
16379 {
16380 pTdlsPeer->isOffChannelSupported = TRUE;
16381 break;
16382 }
16383 }
16384 }
16385 else
16386 {
16387 pTdlsPeer->isOffChannelSupported = FALSE;
16388 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016389 }
16390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16391 "%s: TDLS channel switch request for channel "
16392 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016393 "%d isOffChannelSupported %d", __func__,
16394 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016395 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016396 suppChannelLen,
16397 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016398
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016399 /* TDLS Off Channel, Enable tdls channel switch,
16400 when their is only one tdls link and it supports */
16401 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16402 if ((numCurrTdlsPeers == 1) &&
16403 (TRUE == pTdlsPeer->isOffChannelSupported) &&
16404 (TRUE == pTdlsPeer->isOffChannelConfigured))
16405 {
16406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16407 "%s: Send TDLS channel switch request for channel %d",
16408 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016409
16410 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016411 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
16412 pAdapter->sessionId,
16413 pTdlsPeer->peerMac,
16414 pTdlsPeer->peerParams.channel,
16415 TDLS_OFF_CHANNEL_BW_OFFSET,
16416 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016417 if (ret != VOS_STATUS_SUCCESS) {
16418 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
16419 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016420 }
16421 else
16422 {
16423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16424 "%s: TDLS channel switch request not sent"
16425 " numCurrTdlsPeers %d "
16426 "isOffChannelSupported %d "
16427 "isOffChannelConfigured %d",
16428 __func__, numCurrTdlsPeers,
16429 pTdlsPeer->isOffChannelSupported,
16430 pTdlsPeer->isOffChannelConfigured);
16431 }
16432
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016433 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016434 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016435
16436 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016437 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
16438 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016439 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016440 int ac;
16441 uint8 ucAc[4] = { WLANTL_AC_VO,
16442 WLANTL_AC_VI,
16443 WLANTL_AC_BK,
16444 WLANTL_AC_BE };
16445 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
16446 for(ac=0; ac < 4; ac++)
16447 {
16448 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16449 pTdlsPeer->staId, ucAc[ac],
16450 tlTid[ac], tlTid[ac], 0, 0,
16451 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016452 if (status != VOS_STATUS_SUCCESS) {
16453 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
16454 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016455 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016456 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016457 }
16458
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016459 }
16460 break;
16461 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080016462 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016463 tANI_U16 numCurrTdlsPeers = 0;
16464 hddTdlsPeer_t *connPeer = NULL;
16465
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16467 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
16468 __func__, MAC_ADDR_ARRAY(peer));
16469
Sunil Dutt41de4e22013-11-14 18:09:02 +053016470 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
16471
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016472
Sunil Dutt41de4e22013-11-14 18:09:02 +053016473 if ( NULL == pTdlsPeer ) {
16474 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16475 " (oper %d) not exsting. ignored",
16476 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16477 return -EINVAL;
16478 }
16479
16480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16481 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16482 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16483 "NL80211_TDLS_DISABLE_LINK");
16484
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016485 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080016486 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016487 long status;
16488
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016489 /* set tdls off channel status to false for this peer */
16490 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053016491 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16492 eTDLS_LINK_TEARING,
16493 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
16494 eTDLS_LINK_UNSPECIFIED:
16495 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016496 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
16497
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016498 status = sme_DeleteTdlsPeerSta(
16499 WLAN_HDD_GET_HAL_CTX(pAdapter),
16500 pAdapter->sessionId, peer );
16501 if (status != VOS_STATUS_SUCCESS) {
16502 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16503 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016504
16505 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
16506 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053016507 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053016508 eTDLS_LINK_IDLE,
16509 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016510 if (status <= 0)
16511 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016512 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16513 "%s: Del station failed status %ld",
16514 __func__, status);
16515 return -EPERM;
16516 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016517
16518 /* TDLS Off Channel, Enable tdls channel switch,
16519 when their is only one tdls link and it supports */
16520 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16521 if (numCurrTdlsPeers == 1)
16522 {
16523 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
16524 if ((connPeer) &&
16525 (connPeer->isOffChannelSupported == TRUE) &&
16526 (connPeer->isOffChannelConfigured == TRUE))
16527 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016528 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016529 status = sme_SendTdlsChanSwitchReq(
16530 WLAN_HDD_GET_HAL_CTX(pAdapter),
16531 pAdapter->sessionId,
16532 connPeer->peerMac,
16533 connPeer->peerParams.channel,
16534 TDLS_OFF_CHANNEL_BW_OFFSET,
16535 TDLS_CHANNEL_SWITCH_ENABLE);
16536 if (status != VOS_STATUS_SUCCESS) {
16537 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
16538 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016539 }
16540 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16541 "%s: TDLS channel switch "
16542 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016543 "isOffChannelConfigured %d "
16544 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016545 __func__,
16546 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016547 (connPeer ? connPeer->isOffChannelConfigured : -1),
16548 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016549 }
16550 else
16551 {
16552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16553 "%s: TDLS channel switch request not sent "
16554 "numCurrTdlsPeers %d ",
16555 __func__, numCurrTdlsPeers);
16556 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016557 }
16558 else
16559 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016560 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16561 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080016562 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016563 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016564 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016565 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016566 {
Atul Mittal115287b2014-07-08 13:26:33 +053016567 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016568
Atul Mittal115287b2014-07-08 13:26:33 +053016569 if (0 != status)
16570 {
16571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016572 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053016573 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016574 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053016575 break;
16576 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016577 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016578 {
Atul Mittal115287b2014-07-08 13:26:33 +053016579 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
16580 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016581 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053016582 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016583
Atul Mittal115287b2014-07-08 13:26:33 +053016584 if (0 != status)
16585 {
16586 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016587 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053016588 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053016589 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053016590 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016591 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016592 case NL80211_TDLS_DISCOVERY_REQ:
16593 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016595 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016596 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016597 return -ENOTSUPP;
16598 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16600 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016601 return -ENOTSUPP;
16602 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016603
16604 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016605 return 0;
16606}
Chilam NG571c65a2013-01-19 12:27:36 +053016607
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016608static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016609#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16610 const u8 *peer,
16611#else
16612 u8 *peer,
16613#endif
16614 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016615{
16616 int ret;
16617
16618 vos_ssr_protect(__func__);
16619 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
16620 vos_ssr_unprotect(__func__);
16621
16622 return ret;
16623}
16624
Chilam NG571c65a2013-01-19 12:27:36 +053016625int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
16626 struct net_device *dev, u8 *peer)
16627{
Arif Hussaina7c8e412013-11-20 11:06:42 -080016628 hddLog(VOS_TRACE_LEVEL_INFO,
16629 "tdls send discover req: "MAC_ADDRESS_STR,
16630 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053016631
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016632#if TDLS_MGMT_VERSION2
16633 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16634 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16635#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016636#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
16637 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16638 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
16639#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16640 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16641 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16642#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
16643 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16644 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16645#else
Chilam NG571c65a2013-01-19 12:27:36 +053016646 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16647 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016648#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016649#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053016650}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016651#endif
16652
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016653#ifdef WLAN_FEATURE_GTK_OFFLOAD
16654/*
16655 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
16656 * Callback rountine called upon receiving response for
16657 * get offload info
16658 */
16659void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
16660 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
16661{
16662
16663 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016664 tANI_U8 tempReplayCounter[8];
16665 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016666
16667 ENTER();
16668
16669 if (NULL == pAdapter)
16670 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016672 "%s: HDD adapter is Null", __func__);
16673 return ;
16674 }
16675
16676 if (NULL == pGtkOffloadGetInfoRsp)
16677 {
16678 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16679 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
16680 return ;
16681 }
16682
16683 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
16684 {
16685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16686 "%s: wlan Failed to get replay counter value",
16687 __func__);
16688 return ;
16689 }
16690
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016691 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16692 /* Update replay counter */
16693 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
16694 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16695
16696 {
16697 /* changing from little to big endian since supplicant
16698 * works on big endian format
16699 */
16700 int i;
16701 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16702
16703 for (i = 0; i < 8; i++)
16704 {
16705 tempReplayCounter[7-i] = (tANI_U8)p[i];
16706 }
16707 }
16708
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016709 /* Update replay counter to NL */
16710 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016711 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016712}
16713
16714/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016715 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016716 * This function is used to offload GTK rekeying job to the firmware.
16717 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016718int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016719 struct cfg80211_gtk_rekey_data *data)
16720{
16721 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16722 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16723 hdd_station_ctx_t *pHddStaCtx;
16724 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016725 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016726 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016727 eHalStatus status = eHAL_STATUS_FAILURE;
16728
16729 ENTER();
16730
16731 if (NULL == pAdapter)
16732 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016733 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016734 "%s: HDD adapter is Null", __func__);
16735 return -ENODEV;
16736 }
16737
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016738 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16739 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
16740 pAdapter->sessionId, pAdapter->device_mode));
16741
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016742 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016743 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016744 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016745 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016746 }
16747
16748 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16749 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16750 if (NULL == hHal)
16751 {
16752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16753 "%s: HAL context is Null!!!", __func__);
16754 return -EAGAIN;
16755 }
16756
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016757 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
16758 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
16759 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
16760 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016761 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016762 {
16763 /* changing from big to little endian since driver
16764 * works on little endian format
16765 */
16766 tANI_U8 *p =
16767 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
16768 int i;
16769
16770 for (i = 0; i < 8; i++)
16771 {
16772 p[7-i] = data->replay_ctr[i];
16773 }
16774 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016775
16776 if (TRUE == pHddCtx->hdd_wlan_suspended)
16777 {
16778 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016779 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
16780 sizeof (tSirGtkOffloadParams));
16781 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016782 pAdapter->sessionId);
16783
16784 if (eHAL_STATUS_SUCCESS != status)
16785 {
16786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16787 "%s: sme_SetGTKOffload failed, returned %d",
16788 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016789
16790 /* Need to clear any trace of key value in the memory.
16791 * Thus zero out the memory even though it is local
16792 * variable.
16793 */
16794 vos_mem_zero(&hddGtkOffloadReqParams,
16795 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016796 return status;
16797 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16799 "%s: sme_SetGTKOffload successfull", __func__);
16800 }
16801 else
16802 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16804 "%s: wlan not suspended GTKOffload request is stored",
16805 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016806 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016807
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016808 /* Need to clear any trace of key value in the memory.
16809 * Thus zero out the memory even though it is local
16810 * variable.
16811 */
16812 vos_mem_zero(&hddGtkOffloadReqParams,
16813 sizeof(hddGtkOffloadReqParams));
16814
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016815 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016816 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016817}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016818
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016819int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
16820 struct cfg80211_gtk_rekey_data *data)
16821{
16822 int ret;
16823
16824 vos_ssr_protect(__func__);
16825 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
16826 vos_ssr_unprotect(__func__);
16827
16828 return ret;
16829}
16830#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016831/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016832 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016833 * This function is used to set access control policy
16834 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016835static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16836 struct net_device *dev,
16837 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016838{
16839 int i;
16840 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16841 hdd_hostapd_state_t *pHostapdState;
16842 tsap_Config_t *pConfig;
16843 v_CONTEXT_t pVosContext = NULL;
16844 hdd_context_t *pHddCtx;
16845 int status;
16846
16847 ENTER();
16848
16849 if (NULL == pAdapter)
16850 {
16851 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16852 "%s: HDD adapter is Null", __func__);
16853 return -ENODEV;
16854 }
16855
16856 if (NULL == params)
16857 {
16858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16859 "%s: params is Null", __func__);
16860 return -EINVAL;
16861 }
16862
16863 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16864 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016865 if (0 != status)
16866 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016867 return status;
16868 }
16869
16870 pVosContext = pHddCtx->pvosContext;
16871 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
16872
16873 if (NULL == pHostapdState)
16874 {
16875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16876 "%s: pHostapdState is Null", __func__);
16877 return -EINVAL;
16878 }
16879
16880 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
16881 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016882 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16883 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
16884 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016885
16886 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
16887 {
16888 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
16889
16890 /* default value */
16891 pConfig->num_accept_mac = 0;
16892 pConfig->num_deny_mac = 0;
16893
16894 /**
16895 * access control policy
16896 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
16897 * listed in hostapd.deny file.
16898 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
16899 * listed in hostapd.accept file.
16900 */
16901 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
16902 {
16903 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
16904 }
16905 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
16906 {
16907 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
16908 }
16909 else
16910 {
16911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16912 "%s:Acl Policy : %d is not supported",
16913 __func__, params->acl_policy);
16914 return -ENOTSUPP;
16915 }
16916
16917 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
16918 {
16919 pConfig->num_accept_mac = params->n_acl_entries;
16920 for (i = 0; i < params->n_acl_entries; i++)
16921 {
16922 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16923 "** Add ACL MAC entry %i in WhiletList :"
16924 MAC_ADDRESS_STR, i,
16925 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16926
16927 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
16928 sizeof(qcmacaddr));
16929 }
16930 }
16931 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
16932 {
16933 pConfig->num_deny_mac = params->n_acl_entries;
16934 for (i = 0; i < params->n_acl_entries; i++)
16935 {
16936 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16937 "** Add ACL MAC entry %i in BlackList :"
16938 MAC_ADDRESS_STR, i,
16939 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16940
16941 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
16942 sizeof(qcmacaddr));
16943 }
16944 }
16945
16946 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
16947 {
16948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16949 "%s: SAP Set Mac Acl fail", __func__);
16950 return -EINVAL;
16951 }
16952 }
16953 else
16954 {
16955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016956 "%s: Invalid device_mode = %s (%d)",
16957 __func__, hdd_device_modetoString(pAdapter->device_mode),
16958 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016959 return -EINVAL;
16960 }
16961
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016962 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016963 return 0;
16964}
16965
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016966static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16967 struct net_device *dev,
16968 const struct cfg80211_acl_data *params)
16969{
16970 int ret;
16971 vos_ssr_protect(__func__);
16972 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
16973 vos_ssr_unprotect(__func__);
16974
16975 return ret;
16976}
16977
Leo Chang9056f462013-08-01 19:21:11 -070016978#ifdef WLAN_NL80211_TESTMODE
16979#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070016980void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070016981(
16982 void *pAdapter,
16983 void *indCont
16984)
16985{
Leo Changd9df8aa2013-09-26 13:32:26 -070016986 tSirLPHBInd *lphbInd;
16987 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053016988 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070016989
16990 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016991 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070016992
c_hpothu73f35e62014-04-18 13:40:08 +053016993 if (pAdapter == NULL)
16994 {
16995 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16996 "%s: pAdapter is NULL\n",__func__);
16997 return;
16998 }
16999
Leo Chang9056f462013-08-01 19:21:11 -070017000 if (NULL == indCont)
17001 {
17002 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070017003 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070017004 return;
17005 }
17006
c_hpothu73f35e62014-04-18 13:40:08 +053017007 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070017008 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070017009 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053017010 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070017011 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070017012 GFP_ATOMIC);
17013 if (!skb)
17014 {
17015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17016 "LPHB timeout, NL buffer alloc fail");
17017 return;
17018 }
17019
Leo Changac3ba772013-10-07 09:47:04 -070017020 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070017021 {
17022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17023 "WLAN_HDD_TM_ATTR_CMD put fail");
17024 goto nla_put_failure;
17025 }
Leo Changac3ba772013-10-07 09:47:04 -070017026 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070017027 {
17028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17029 "WLAN_HDD_TM_ATTR_TYPE put fail");
17030 goto nla_put_failure;
17031 }
Leo Changac3ba772013-10-07 09:47:04 -070017032 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070017033 sizeof(tSirLPHBInd), lphbInd))
17034 {
17035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17036 "WLAN_HDD_TM_ATTR_DATA put fail");
17037 goto nla_put_failure;
17038 }
Leo Chang9056f462013-08-01 19:21:11 -070017039 cfg80211_testmode_event(skb, GFP_ATOMIC);
17040 return;
17041
17042nla_put_failure:
17043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17044 "NLA Put fail");
17045 kfree_skb(skb);
17046
17047 return;
17048}
17049#endif /* FEATURE_WLAN_LPHB */
17050
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017051static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070017052{
17053 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
17054 int err = 0;
17055#ifdef FEATURE_WLAN_LPHB
17056 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070017057 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017058
17059 ENTER();
17060
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017061 err = wlan_hdd_validate_context(pHddCtx);
17062 if (0 != err)
17063 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017064 return err;
17065 }
Leo Chang9056f462013-08-01 19:21:11 -070017066#endif /* FEATURE_WLAN_LPHB */
17067
17068 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
17069 if (err)
17070 {
17071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17072 "%s Testmode INV ATTR", __func__);
17073 return err;
17074 }
17075
17076 if (!tb[WLAN_HDD_TM_ATTR_CMD])
17077 {
17078 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17079 "%s Testmode INV CMD", __func__);
17080 return -EINVAL;
17081 }
17082
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017083 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17084 TRACE_CODE_HDD_CFG80211_TESTMODE,
17085 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070017086 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
17087 {
17088#ifdef FEATURE_WLAN_LPHB
17089 /* Low Power Heartbeat configuration request */
17090 case WLAN_HDD_TM_CMD_WLAN_HB:
17091 {
17092 int buf_len;
17093 void *buf;
17094 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080017095 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070017096
17097 if (!tb[WLAN_HDD_TM_ATTR_DATA])
17098 {
17099 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17100 "%s Testmode INV DATA", __func__);
17101 return -EINVAL;
17102 }
17103
17104 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
17105 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080017106
17107 hb_params_temp =(tSirLPHBReq *)buf;
17108 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
17109 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
17110 return -EINVAL;
17111
Leo Chang9056f462013-08-01 19:21:11 -070017112 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
17113 if (NULL == hb_params)
17114 {
17115 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17116 "%s Request Buffer Alloc Fail", __func__);
17117 return -EINVAL;
17118 }
17119
17120 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070017121 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
17122 hb_params,
17123 wlan_hdd_cfg80211_lphb_ind_handler);
17124 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070017125 {
Leo Changd9df8aa2013-09-26 13:32:26 -070017126 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17127 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070017128 vos_mem_free(hb_params);
17129 }
Leo Chang9056f462013-08-01 19:21:11 -070017130 return 0;
17131 }
17132#endif /* FEATURE_WLAN_LPHB */
17133 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17135 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070017136 return -EOPNOTSUPP;
17137 }
17138
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017139 EXIT();
17140 return err;
Leo Chang9056f462013-08-01 19:21:11 -070017141}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017142
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053017143static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
17144#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
17145 struct wireless_dev *wdev,
17146#endif
17147 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017148{
17149 int ret;
17150
17151 vos_ssr_protect(__func__);
17152 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
17153 vos_ssr_unprotect(__func__);
17154
17155 return ret;
17156}
Leo Chang9056f462013-08-01 19:21:11 -070017157#endif /* CONFIG_NL80211_TESTMODE */
17158
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017159static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017160 struct net_device *dev,
17161 int idx, struct survey_info *survey)
17162{
17163 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17164 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053017165 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017166 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053017167 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017168 v_S7_t snr,rssi;
17169 int status, i, j, filled = 0;
17170
17171 ENTER();
17172
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017173 if (NULL == pAdapter)
17174 {
17175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17176 "%s: HDD adapter is Null", __func__);
17177 return -ENODEV;
17178 }
17179
17180 if (NULL == wiphy)
17181 {
17182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17183 "%s: wiphy is Null", __func__);
17184 return -ENODEV;
17185 }
17186
17187 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17188 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017189 if (0 != status)
17190 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017191 return status;
17192 }
17193
Mihir Sheted9072e02013-08-21 17:02:29 +053017194 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17195
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017196 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053017197 0 != pAdapter->survey_idx ||
17198 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017199 {
17200 /* The survey dump ops when implemented completely is expected to
17201 * return a survey of all channels and the ops is called by the
17202 * kernel with incremental values of the argument 'idx' till it
17203 * returns -ENONET. But we can only support the survey for the
17204 * operating channel for now. survey_idx is used to track
17205 * that the ops is called only once and then return -ENONET for
17206 * the next iteration
17207 */
17208 pAdapter->survey_idx = 0;
17209 return -ENONET;
17210 }
17211
Mukul Sharma9d5233b2015-06-11 20:28:20 +053017212 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17213 {
17214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17215 "%s: Roaming in progress, hence return ", __func__);
17216 return -ENONET;
17217 }
17218
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017219 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17220
17221 wlan_hdd_get_snr(pAdapter, &snr);
17222 wlan_hdd_get_rssi(pAdapter, &rssi);
17223
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017224 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17225 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
17226 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017227 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
17228 hdd_wlan_get_freq(channel, &freq);
17229
17230
17231 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
17232 {
17233 if (NULL == wiphy->bands[i])
17234 {
17235 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
17236 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
17237 continue;
17238 }
17239
17240 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
17241 {
17242 struct ieee80211_supported_band *band = wiphy->bands[i];
17243
17244 if (band->channels[j].center_freq == (v_U16_t)freq)
17245 {
17246 survey->channel = &band->channels[j];
17247 /* The Rx BDs contain SNR values in dB for the received frames
17248 * while the supplicant expects noise. So we calculate and
17249 * return the value of noise (dBm)
17250 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
17251 */
17252 survey->noise = rssi - snr;
17253 survey->filled = SURVEY_INFO_NOISE_DBM;
17254 filled = 1;
17255 }
17256 }
17257 }
17258
17259 if (filled)
17260 pAdapter->survey_idx = 1;
17261 else
17262 {
17263 pAdapter->survey_idx = 0;
17264 return -ENONET;
17265 }
17266
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017267 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017268 return 0;
17269}
17270
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017271static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
17272 struct net_device *dev,
17273 int idx, struct survey_info *survey)
17274{
17275 int ret;
17276
17277 vos_ssr_protect(__func__);
17278 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
17279 vos_ssr_unprotect(__func__);
17280
17281 return ret;
17282}
17283
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017284/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017285 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017286 * this is called when cfg80211 driver resume
17287 * driver updates latest sched_scan scan result(if any) to cfg80211 database
17288 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017289int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017290{
17291 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17292 hdd_adapter_t *pAdapter;
17293 hdd_adapter_list_node_t *pAdapterNode, *pNext;
17294 VOS_STATUS status = VOS_STATUS_SUCCESS;
17295
17296 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017297
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017298 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017299 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017300 return 0;
17301 }
17302
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017303 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
17304 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017305 spin_lock(&pHddCtx->schedScan_lock);
17306 pHddCtx->isWiphySuspended = FALSE;
17307 if (TRUE != pHddCtx->isSchedScanUpdatePending)
17308 {
17309 spin_unlock(&pHddCtx->schedScan_lock);
17310 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17311 "%s: Return resume is not due to PNO indication", __func__);
17312 return 0;
17313 }
17314 // Reset flag to avoid updatating cfg80211 data old results again
17315 pHddCtx->isSchedScanUpdatePending = FALSE;
17316 spin_unlock(&pHddCtx->schedScan_lock);
17317
17318 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
17319
17320 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
17321 {
17322 pAdapter = pAdapterNode->pAdapter;
17323 if ( (NULL != pAdapter) &&
17324 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
17325 {
17326 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017327 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17329 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017330 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017331 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017332 {
17333 /* Acquire wakelock to handle the case where APP's tries to
17334 * suspend immediately after updating the scan results. Whis
17335 * results in app's is in suspended state and not able to
17336 * process the connect request to AP
17337 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053017338 hdd_prevent_suspend_timeout(2000,
17339 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017340 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017341 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017342
17343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17344 "%s : cfg80211 scan result database updated", __func__);
17345
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017346 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017347 return 0;
17348
17349 }
17350 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17351 pAdapterNode = pNext;
17352 }
17353
17354 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17355 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017356 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017357 return 0;
17358}
17359
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017360int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
17361{
17362 int ret;
17363
17364 vos_ssr_protect(__func__);
17365 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
17366 vos_ssr_unprotect(__func__);
17367
17368 return ret;
17369}
17370
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017371/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017372 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017373 * this is called when cfg80211 driver suspends
17374 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017375int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017376 struct cfg80211_wowlan *wow)
17377{
17378 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017379 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017380
17381 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017382
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017383 ret = wlan_hdd_validate_context(pHddCtx);
17384 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017385 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017386 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017387 }
17388
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017389
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017390 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17391 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
17392 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017393 pHddCtx->isWiphySuspended = TRUE;
17394
17395 EXIT();
17396
17397 return 0;
17398}
17399
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017400int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
17401 struct cfg80211_wowlan *wow)
17402{
17403 int ret;
17404
17405 vos_ssr_protect(__func__);
17406 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
17407 vos_ssr_unprotect(__func__);
17408
17409 return ret;
17410}
Jeff Johnson295189b2012-06-20 16:38:30 -070017411/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017412static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070017413{
17414 .add_virtual_intf = wlan_hdd_add_virtual_intf,
17415 .del_virtual_intf = wlan_hdd_del_virtual_intf,
17416 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
17417 .change_station = wlan_hdd_change_station,
17418#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
17419 .add_beacon = wlan_hdd_cfg80211_add_beacon,
17420 .del_beacon = wlan_hdd_cfg80211_del_beacon,
17421 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017422#else
17423 .start_ap = wlan_hdd_cfg80211_start_ap,
17424 .change_beacon = wlan_hdd_cfg80211_change_beacon,
17425 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070017426#endif
17427 .change_bss = wlan_hdd_cfg80211_change_bss,
17428 .add_key = wlan_hdd_cfg80211_add_key,
17429 .get_key = wlan_hdd_cfg80211_get_key,
17430 .del_key = wlan_hdd_cfg80211_del_key,
17431 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017432#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070017433 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017434#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017435 .scan = wlan_hdd_cfg80211_scan,
17436 .connect = wlan_hdd_cfg80211_connect,
17437 .disconnect = wlan_hdd_cfg80211_disconnect,
17438 .join_ibss = wlan_hdd_cfg80211_join_ibss,
17439 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
17440 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
17441 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
17442 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070017443 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
17444 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053017445 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070017446#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17447 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
17448 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
17449 .set_txq_params = wlan_hdd_set_txq_params,
17450#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017451 .get_station = wlan_hdd_cfg80211_get_station,
17452 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
17453 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017454 .add_station = wlan_hdd_cfg80211_add_station,
17455#ifdef FEATURE_WLAN_LFR
17456 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
17457 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
17458 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
17459#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017460#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
17461 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
17462#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017463#ifdef FEATURE_WLAN_TDLS
17464 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
17465 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
17466#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017467#ifdef WLAN_FEATURE_GTK_OFFLOAD
17468 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
17469#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017470#ifdef FEATURE_WLAN_SCAN_PNO
17471 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
17472 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
17473#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017474 .resume = wlan_hdd_cfg80211_resume_wlan,
17475 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017476 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070017477#ifdef WLAN_NL80211_TESTMODE
17478 .testmode_cmd = wlan_hdd_cfg80211_testmode,
17479#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017480 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070017481};
17482