blob: c3b34a954ac8b2b5fe2d7cd0933f80eb6f799e5c [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Masti, Narayanraddie1892a52015-12-15 15:01:01 +05302 * Copyright (c) 2012-2016 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"
c_manjeecfd1efb2015-09-25 19:32:34 +053099#include "wlan_logging_sock_svc.h"
Agrawal Ashishcfe83282016-09-29 13:03:45 +0530100#include "wlan_hdd_misc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530101
Jeff Johnson295189b2012-06-20 16:38:30 -0700102
103#define g_mode_rates_size (12)
104#define a_mode_rates_size (8)
105#define FREQ_BASE_80211G (2407)
106#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700107#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530108#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800110 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700111
112#define HDD2GHZCHAN(freq, chan, flag) { \
113 .band = IEEE80211_BAND_2GHZ, \
114 .center_freq = (freq), \
115 .hw_value = (chan),\
116 .flags = (flag), \
117 .max_antenna_gain = 0 ,\
118 .max_power = 30, \
119}
120
121#define HDD5GHZCHAN(freq, chan, flag) { \
122 .band = IEEE80211_BAND_5GHZ, \
123 .center_freq = (freq), \
124 .hw_value = (chan),\
125 .flags = (flag), \
126 .max_antenna_gain = 0 ,\
127 .max_power = 30, \
128}
129
130#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
131{\
132 .bitrate = rate, \
133 .hw_value = rate_id, \
134 .flags = flag, \
135}
136
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530137#ifdef WLAN_FEATURE_VOWIFI_11R
138#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
139#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
140#endif
141
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530142#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530143#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530144
Sunil Duttc69bccb2014-05-26 21:30:20 +0530145#ifdef WLAN_FEATURE_LINK_LAYER_STATS
146/*
147 * Used to allocate the size of 4096 for the link layer stats.
148 * The size of 4096 is considered assuming that all data per
149 * respective event fit with in the limit.Please take a call
150 * on the limit based on the data requirements on link layer
151 * statistics.
152 */
153#define LL_STATS_EVENT_BUF_SIZE 4096
154#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530155#ifdef WLAN_FEATURE_EXTSCAN
156/*
157 * Used to allocate the size of 4096 for the EXTScan NL data.
158 * The size of 4096 is considered assuming that all data per
159 * respective event fit with in the limit.Please take a call
160 * on the limit based on the data requirements.
161 */
162
163#define EXTSCAN_EVENT_BUF_SIZE 4096
164#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
165#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530166
Atul Mittal115287b2014-07-08 13:26:33 +0530167/*EXT TDLS*/
168/*
169 * Used to allocate the size of 4096 for the TDLS.
170 * The size of 4096 is considered assuming that all data per
171 * respective event fit with in the limit.Please take a call
172 * on the limit based on the data requirements on link layer
173 * statistics.
174 */
175#define EXTTDLS_EVENT_BUF_SIZE 4096
176
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530177/*
178 * Values for Mac spoofing feature
179 *
180 */
181#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
182#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
183#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530184#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
185
Anurag Chouhan343af7e2016-12-16 13:11:19 +0530186/*
187 * max_sched_scan_plans defined to 10
188 */
189#define MAX_SCHED_SCAN_PLANS 10
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530190
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530191static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700192{
193 WLAN_CIPHER_SUITE_WEP40,
194 WLAN_CIPHER_SUITE_WEP104,
195 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800196#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700197#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
198 WLAN_CIPHER_SUITE_KRK,
199 WLAN_CIPHER_SUITE_CCMP,
200#else
201 WLAN_CIPHER_SUITE_CCMP,
202#endif
203#ifdef FEATURE_WLAN_WAPI
204 WLAN_CIPHER_SUITE_SMS4,
205#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700206#ifdef WLAN_FEATURE_11W
207 WLAN_CIPHER_SUITE_AES_CMAC,
208#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700209};
210
211static inline int is_broadcast_ether_addr(const u8 *addr)
212{
213 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
214 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
215}
216
Agrawal Ashish97dec502015-11-26 20:20:58 +0530217const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530218{
Jeff Johnson295189b2012-06-20 16:38:30 -0700219 HDD2GHZCHAN(2412, 1, 0) ,
220 HDD2GHZCHAN(2417, 2, 0) ,
221 HDD2GHZCHAN(2422, 3, 0) ,
222 HDD2GHZCHAN(2427, 4, 0) ,
223 HDD2GHZCHAN(2432, 5, 0) ,
224 HDD2GHZCHAN(2437, 6, 0) ,
225 HDD2GHZCHAN(2442, 7, 0) ,
226 HDD2GHZCHAN(2447, 8, 0) ,
227 HDD2GHZCHAN(2452, 9, 0) ,
228 HDD2GHZCHAN(2457, 10, 0) ,
229 HDD2GHZCHAN(2462, 11, 0) ,
230 HDD2GHZCHAN(2467, 12, 0) ,
231 HDD2GHZCHAN(2472, 13, 0) ,
232 HDD2GHZCHAN(2484, 14, 0) ,
233};
234
Agrawal Ashish97dec502015-11-26 20:20:58 +0530235const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700236{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700237 HDD5GHZCHAN(4920, 240, 0) ,
238 HDD5GHZCHAN(4940, 244, 0) ,
239 HDD5GHZCHAN(4960, 248, 0) ,
240 HDD5GHZCHAN(4980, 252, 0) ,
241 HDD5GHZCHAN(5040, 208, 0) ,
242 HDD5GHZCHAN(5060, 212, 0) ,
243 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700244 HDD5GHZCHAN(5180, 36, 0) ,
245 HDD5GHZCHAN(5200, 40, 0) ,
246 HDD5GHZCHAN(5220, 44, 0) ,
247 HDD5GHZCHAN(5240, 48, 0) ,
248 HDD5GHZCHAN(5260, 52, 0) ,
249 HDD5GHZCHAN(5280, 56, 0) ,
250 HDD5GHZCHAN(5300, 60, 0) ,
251 HDD5GHZCHAN(5320, 64, 0) ,
252 HDD5GHZCHAN(5500,100, 0) ,
253 HDD5GHZCHAN(5520,104, 0) ,
254 HDD5GHZCHAN(5540,108, 0) ,
255 HDD5GHZCHAN(5560,112, 0) ,
256 HDD5GHZCHAN(5580,116, 0) ,
257 HDD5GHZCHAN(5600,120, 0) ,
258 HDD5GHZCHAN(5620,124, 0) ,
259 HDD5GHZCHAN(5640,128, 0) ,
260 HDD5GHZCHAN(5660,132, 0) ,
261 HDD5GHZCHAN(5680,136, 0) ,
262 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800263#ifdef FEATURE_WLAN_CH144
264 HDD5GHZCHAN(5720,144, 0) ,
265#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700266 HDD5GHZCHAN(5745,149, 0) ,
267 HDD5GHZCHAN(5765,153, 0) ,
268 HDD5GHZCHAN(5785,157, 0) ,
269 HDD5GHZCHAN(5805,161, 0) ,
270 HDD5GHZCHAN(5825,165, 0) ,
271};
272
273static struct ieee80211_rate g_mode_rates[] =
274{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530275 HDD_G_MODE_RATETAB(10, 0x1, 0),
276 HDD_G_MODE_RATETAB(20, 0x2, 0),
277 HDD_G_MODE_RATETAB(55, 0x4, 0),
278 HDD_G_MODE_RATETAB(110, 0x8, 0),
279 HDD_G_MODE_RATETAB(60, 0x10, 0),
280 HDD_G_MODE_RATETAB(90, 0x20, 0),
281 HDD_G_MODE_RATETAB(120, 0x40, 0),
282 HDD_G_MODE_RATETAB(180, 0x80, 0),
283 HDD_G_MODE_RATETAB(240, 0x100, 0),
284 HDD_G_MODE_RATETAB(360, 0x200, 0),
285 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700286 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530287};
Jeff Johnson295189b2012-06-20 16:38:30 -0700288
289static struct ieee80211_rate a_mode_rates[] =
290{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530291 HDD_G_MODE_RATETAB(60, 0x10, 0),
292 HDD_G_MODE_RATETAB(90, 0x20, 0),
293 HDD_G_MODE_RATETAB(120, 0x40, 0),
294 HDD_G_MODE_RATETAB(180, 0x80, 0),
295 HDD_G_MODE_RATETAB(240, 0x100, 0),
296 HDD_G_MODE_RATETAB(360, 0x200, 0),
297 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 HDD_G_MODE_RATETAB(540, 0x800, 0),
299};
300
301static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
302{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530303 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700304 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
305 .band = IEEE80211_BAND_2GHZ,
306 .bitrates = g_mode_rates,
307 .n_bitrates = g_mode_rates_size,
308 .ht_cap.ht_supported = 1,
309 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
310 | IEEE80211_HT_CAP_GRN_FLD
311 | IEEE80211_HT_CAP_DSSSCCK40
312 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
313 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
314 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
315 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
316 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
317 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
318};
319
Jeff Johnson295189b2012-06-20 16:38:30 -0700320static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
321{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530322 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
324 .band = IEEE80211_BAND_5GHZ,
325 .bitrates = a_mode_rates,
326 .n_bitrates = a_mode_rates_size,
327 .ht_cap.ht_supported = 1,
328 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
329 | IEEE80211_HT_CAP_GRN_FLD
330 | IEEE80211_HT_CAP_DSSSCCK40
331 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
332 | IEEE80211_HT_CAP_SGI_40
333 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
334 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
335 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
336 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
337 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
338 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
339};
340
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530341/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700342 TX/RX direction for each kind of interface */
343static const struct ieee80211_txrx_stypes
344wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
345 [NL80211_IFTYPE_STATION] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ACTION) |
348 BIT(SIR_MAC_MGMT_PROBE_REQ),
349 },
350 [NL80211_IFTYPE_AP] = {
351 .tx = 0xffff,
352 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
353 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
354 BIT(SIR_MAC_MGMT_PROBE_REQ) |
355 BIT(SIR_MAC_MGMT_DISASSOC) |
356 BIT(SIR_MAC_MGMT_AUTH) |
357 BIT(SIR_MAC_MGMT_DEAUTH) |
358 BIT(SIR_MAC_MGMT_ACTION),
359 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700360 [NL80211_IFTYPE_ADHOC] = {
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 Johnson295189b2012-06-20 16:38:30 -0700370 [NL80211_IFTYPE_P2P_CLIENT] = {
371 .tx = 0xffff,
372 .rx = BIT(SIR_MAC_MGMT_ACTION) |
373 BIT(SIR_MAC_MGMT_PROBE_REQ),
374 },
375 [NL80211_IFTYPE_P2P_GO] = {
376 /* This is also same as for SoftAP */
377 .tx = 0xffff,
378 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
379 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
380 BIT(SIR_MAC_MGMT_PROBE_REQ) |
381 BIT(SIR_MAC_MGMT_DISASSOC) |
382 BIT(SIR_MAC_MGMT_AUTH) |
383 BIT(SIR_MAC_MGMT_DEAUTH) |
384 BIT(SIR_MAC_MGMT_ACTION),
385 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700386};
387
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800388#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800389static const struct ieee80211_iface_limit
390wlan_hdd_iface_limit[] = {
391 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800392 /* max = 3 ; Our driver create two interfaces during driver init
393 * wlan0 and p2p0 interfaces. p2p0 is considered as station
394 * interface until a group is formed. In JB architecture, once the
395 * group is formed, interface type of p2p0 is changed to P2P GO or
396 * Client.
397 * When supplicant remove the group, it first issue a set interface
398 * cmd to change the mode back to Station. In JB this works fine as
399 * we advertize two station type interface during driver init.
400 * Some vendors create separate interface for P2P GO/Client,
401 * after group formation(Third one). But while group remove
402 * supplicant first tries to change the mode(3rd interface) to STATION
403 * But as we advertized only two sta type interfaces nl80211 was
404 * returning error for the third one which was leading to failure in
405 * delete interface. Ideally while removing the group, supplicant
406 * should not try to change the 3rd interface mode to Station type.
407 * Till we get a fix in wpa_supplicant, we advertize max STA
408 * interface type to 3
409 */
410 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 .types = BIT(NL80211_IFTYPE_STATION),
412 },
413 {
414 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700415 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800416 },
417 {
418 .max = 1,
419 .types = BIT(NL80211_IFTYPE_P2P_GO) |
420 BIT(NL80211_IFTYPE_P2P_CLIENT),
421 },
422};
423
424/* By default, only single channel concurrency is allowed */
425static struct ieee80211_iface_combination
426wlan_hdd_iface_combination = {
427 .limits = wlan_hdd_iface_limit,
428 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800429 /*
430 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
431 * and p2p0 interfaces during driver init
432 * Some vendors create separate interface for P2P operations.
433 * wlan0: STA interface
434 * p2p0: P2P Device interface, action frames goes
435 * through this interface.
436 * p2p-xx: P2P interface, After GO negotiation this interface is
437 * created for p2p operations(GO/CLIENT interface).
438 */
439 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800440 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
441 .beacon_int_infra_match = false,
442};
443#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800444
Jeff Johnson295189b2012-06-20 16:38:30 -0700445static struct cfg80211_ops wlan_hdd_cfg80211_ops;
446
447/* Data rate 100KBPS based on IE Index */
448struct index_data_rate_type
449{
450 v_U8_t beacon_rate_index;
451 v_U16_t supported_rate[4];
452};
453
454/* 11B, 11G Rate table include Basic rate and Extended rate
455 The IDX field is the rate index
456 The HI field is the rate when RSSI is strong or being ignored
457 (in this case we report actual rate)
458 The MID field is the rate when RSSI is moderate
459 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
460 The LO field is the rate when RSSI is low
461 (in this case we don't report rates, actual current rate used)
462 */
463static const struct
464{
465 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700466 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700467} supported_data_rate[] =
468{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700469/* IDX HI HM LM LO (RSSI-based index */
470 {2, { 10, 10, 10, 0}},
471 {4, { 20, 20, 10, 0}},
472 {11, { 55, 20, 10, 0}},
473 {12, { 60, 55, 20, 0}},
474 {18, { 90, 55, 20, 0}},
475 {22, {110, 55, 20, 0}},
476 {24, {120, 90, 60, 0}},
477 {36, {180, 120, 60, 0}},
478 {44, {220, 180, 60, 0}},
479 {48, {240, 180, 90, 0}},
480 {66, {330, 180, 90, 0}},
481 {72, {360, 240, 90, 0}},
482 {96, {480, 240, 120, 0}},
483 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700484};
485
486/* MCS Based rate table */
487static struct index_data_rate_type supported_mcs_rate[] =
488{
489/* MCS L20 L40 S20 S40 */
490 {0, {65, 135, 72, 150}},
491 {1, {130, 270, 144, 300}},
492 {2, {195, 405, 217, 450}},
493 {3, {260, 540, 289, 600}},
494 {4, {390, 810, 433, 900}},
495 {5, {520, 1080, 578, 1200}},
496 {6, {585, 1215, 650, 1350}},
497 {7, {650, 1350, 722, 1500}}
498};
499
Leo Chang6f8870f2013-03-26 18:11:36 -0700500#ifdef WLAN_FEATURE_11AC
501
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530502#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700503
504struct index_vht_data_rate_type
505{
506 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530507 v_U16_t supported_VHT80_rate[2];
508 v_U16_t supported_VHT40_rate[2];
509 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700510};
511
512typedef enum
513{
514 DATA_RATE_11AC_MAX_MCS_7,
515 DATA_RATE_11AC_MAX_MCS_8,
516 DATA_RATE_11AC_MAX_MCS_9,
517 DATA_RATE_11AC_MAX_MCS_NA
518} eDataRate11ACMaxMcs;
519
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530520/* SSID broadcast type */
521typedef enum eSSIDBcastType
522{
523 eBCAST_UNKNOWN = 0,
524 eBCAST_NORMAL = 1,
525 eBCAST_HIDDEN = 2,
526} tSSIDBcastType;
527
Leo Chang6f8870f2013-03-26 18:11:36 -0700528/* MCS Based VHT rate table */
529static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
530{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530531/* MCS L80 S80 L40 S40 L20 S40*/
532 {0, {293, 325}, {135, 150}, {65, 72}},
533 {1, {585, 650}, {270, 300}, {130, 144}},
534 {2, {878, 975}, {405, 450}, {195, 217}},
535 {3, {1170, 1300}, {540, 600}, {260, 289}},
536 {4, {1755, 1950}, {810, 900}, {390, 433}},
537 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
538 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
539 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
540 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
541 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700542};
543#endif /* WLAN_FEATURE_11AC */
544
c_hpothu79aab322014-07-14 21:11:01 +0530545/*array index points to MCS and array value points respective rssi*/
546static int rssiMcsTbl[][10] =
547{
548/*MCS 0 1 2 3 4 5 6 7 8 9*/
549 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
550 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
551 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
552};
553
Jeff Johnson295189b2012-06-20 16:38:30 -0700554extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530555#ifdef FEATURE_WLAN_SCAN_PNO
556static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
557#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700558
Leo Chang9056f462013-08-01 19:21:11 -0700559#ifdef WLAN_NL80211_TESTMODE
560enum wlan_hdd_tm_attr
561{
562 WLAN_HDD_TM_ATTR_INVALID = 0,
563 WLAN_HDD_TM_ATTR_CMD = 1,
564 WLAN_HDD_TM_ATTR_DATA = 2,
565 WLAN_HDD_TM_ATTR_TYPE = 3,
566 /* keep last */
567 WLAN_HDD_TM_ATTR_AFTER_LAST,
568 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
569};
570
571enum wlan_hdd_tm_cmd
572{
573 WLAN_HDD_TM_CMD_WLAN_HB = 1,
574};
575
576#define WLAN_HDD_TM_DATA_MAX_LEN 5000
577
578static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
579{
580 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
581 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
582 .len = WLAN_HDD_TM_DATA_MAX_LEN },
583};
584#endif /* WLAN_NL80211_TESTMODE */
585
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800586#ifdef FEATURE_WLAN_CH_AVOID
587/*
588 * FUNCTION: wlan_hdd_send_avoid_freq_event
589 * This is called when wlan driver needs to send vendor specific
590 * avoid frequency range event to userspace
591 */
592int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
593 tHddAvoidFreqList *pAvoidFreqList)
594{
595 struct sk_buff *vendor_event;
596
597 ENTER();
598
599 if (!pHddCtx)
600 {
601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
602 "%s: HDD context is null", __func__);
603 return -1;
604 }
605
606 if (!pAvoidFreqList)
607 {
608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
609 "%s: pAvoidFreqList is null", __func__);
610 return -1;
611 }
612
613 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530614#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
615 NULL,
616#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800617 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530618 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800619 GFP_KERNEL);
620 if (!vendor_event)
621 {
622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
623 "%s: cfg80211_vendor_event_alloc failed", __func__);
624 return -1;
625 }
626
627 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
628 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
629
630 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
631
632 EXIT();
633 return 0;
634}
635#endif /* FEATURE_WLAN_CH_AVOID */
636
Srinivas Dasari030bad32015-02-18 23:23:54 +0530637/*
638 * FUNCTION: __wlan_hdd_cfg80211_nan_request
639 * This is called when wlan driver needs to send vendor specific
640 * nan request event.
641 */
642static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
643 struct wireless_dev *wdev,
644 const void *data, int data_len)
645{
646 tNanRequestReq nan_req;
647 VOS_STATUS status;
648 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530649 struct net_device *dev = wdev->netdev;
650 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
651 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530652 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
653
654 if (0 == data_len)
655 {
656 hddLog(VOS_TRACE_LEVEL_ERROR,
657 FL("NAN - Invalid Request, length = 0"));
658 return ret_val;
659 }
660
661 if (NULL == data)
662 {
663 hddLog(VOS_TRACE_LEVEL_ERROR,
664 FL("NAN - Invalid Request, data is NULL"));
665 return ret_val;
666 }
667
668 status = wlan_hdd_validate_context(pHddCtx);
669 if (0 != status)
670 {
671 hddLog(VOS_TRACE_LEVEL_ERROR,
672 FL("HDD context is not valid"));
673 return -EINVAL;
674 }
675
676 hddLog(LOG1, FL("Received NAN command"));
677 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
678 (tANI_U8 *)data, data_len);
679
680 /* check the NAN Capability */
681 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
682 {
683 hddLog(VOS_TRACE_LEVEL_ERROR,
684 FL("NAN is not supported by Firmware"));
685 return -EINVAL;
686 }
687
688 nan_req.request_data_len = data_len;
689 nan_req.request_data = data;
690
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530691 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530692 if (VOS_STATUS_SUCCESS == status)
693 {
694 ret_val = 0;
695 }
696 return ret_val;
697}
698
699/*
700 * FUNCTION: wlan_hdd_cfg80211_nan_request
701 * Wrapper to protect the nan vendor command from ssr
702 */
703static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
704 struct wireless_dev *wdev,
705 const void *data, int data_len)
706{
707 int ret;
708
709 vos_ssr_protect(__func__);
710 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
711 vos_ssr_unprotect(__func__);
712
713 return ret;
714}
715
716/*
717 * FUNCTION: wlan_hdd_cfg80211_nan_callback
718 * This is a callback function and it gets called
719 * when we need to report nan response event to
720 * upper layers.
721 */
722static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
723{
724 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
725 struct sk_buff *vendor_event;
726 int status;
727 tSirNanEvent *data;
728
729 ENTER();
730 if (NULL == msg)
731 {
732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
733 FL(" msg received here is null"));
734 return;
735 }
736 data = msg;
737
738 status = wlan_hdd_validate_context(pHddCtx);
739
740 if (0 != status)
741 {
742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
743 FL("HDD context is not valid"));
744 return;
745 }
746
747 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530748#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
749 NULL,
750#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530751 data->event_data_len +
752 NLMSG_HDRLEN,
753 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
754 GFP_KERNEL);
755
756 if (!vendor_event)
757 {
758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
759 FL("cfg80211_vendor_event_alloc failed"));
760 return;
761 }
762 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
763 data->event_data_len, data->event_data))
764 {
765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
766 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
767 kfree_skb(vendor_event);
768 return;
769 }
770 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
771 EXIT();
772}
773
774/*
775 * FUNCTION: wlan_hdd_cfg80211_nan_init
776 * This function is called to register the callback to sme layer
777 */
778inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
779{
780 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
781}
782
783
Sunil Duttc69bccb2014-05-26 21:30:20 +0530784#ifdef WLAN_FEATURE_LINK_LAYER_STATS
785
786static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
787 struct sk_buff *vendor_event)
788{
789 if (nla_put_u8(vendor_event,
790 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
791 stats->rate.preamble) ||
792 nla_put_u8(vendor_event,
793 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
794 stats->rate.nss) ||
795 nla_put_u8(vendor_event,
796 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
797 stats->rate.bw) ||
798 nla_put_u8(vendor_event,
799 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
800 stats->rate.rateMcsIdx) ||
801 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
802 stats->rate.bitrate ) ||
803 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
804 stats->txMpdu ) ||
805 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
806 stats->rxMpdu ) ||
807 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
808 stats->mpduLost ) ||
809 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
810 stats->retries) ||
811 nla_put_u32(vendor_event,
812 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
813 stats->retriesShort ) ||
814 nla_put_u32(vendor_event,
815 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
816 stats->retriesLong))
817 {
818 hddLog(VOS_TRACE_LEVEL_ERROR,
819 FL("QCA_WLAN_VENDOR_ATTR put fail"));
820 return FALSE;
821 }
822 return TRUE;
823}
824
825static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
826 struct sk_buff *vendor_event)
827{
828 u32 i = 0;
829 struct nlattr *rateInfo;
830 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
831 stats->type) ||
832 nla_put(vendor_event,
833 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
834 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
835 nla_put_u32(vendor_event,
836 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
837 stats->capabilities) ||
838 nla_put_u32(vendor_event,
839 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
840 stats->numRate))
841 {
842 hddLog(VOS_TRACE_LEVEL_ERROR,
843 FL("QCA_WLAN_VENDOR_ATTR put fail"));
844 goto error;
845 }
846
847 rateInfo = nla_nest_start(vendor_event,
848 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530849 if(!rateInfo)
850 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530851 for (i = 0; i < stats->numRate; i++)
852 {
853 struct nlattr *rates;
854 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
855 stats->rateStats +
856 (i * sizeof(tSirWifiRateStat)));
857 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530858 if(!rates)
859 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530860
861 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
862 {
863 hddLog(VOS_TRACE_LEVEL_ERROR,
864 FL("QCA_WLAN_VENDOR_ATTR put fail"));
865 return FALSE;
866 }
867 nla_nest_end(vendor_event, rates);
868 }
869 nla_nest_end(vendor_event, rateInfo);
870
871 return TRUE;
872error:
873 return FALSE;
874}
875
876static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
877 struct sk_buff *vendor_event)
878{
879 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
880 stats->ac ) ||
881 nla_put_u32(vendor_event,
882 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
883 stats->txMpdu ) ||
884 nla_put_u32(vendor_event,
885 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
886 stats->rxMpdu ) ||
887 nla_put_u32(vendor_event,
888 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
889 stats->txMcast ) ||
890 nla_put_u32(vendor_event,
891 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
892 stats->rxMcast ) ||
893 nla_put_u32(vendor_event,
894 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
895 stats->rxAmpdu ) ||
896 nla_put_u32(vendor_event,
897 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
898 stats->txAmpdu ) ||
899 nla_put_u32(vendor_event,
900 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
901 stats->mpduLost )||
902 nla_put_u32(vendor_event,
903 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
904 stats->retries ) ||
905 nla_put_u32(vendor_event,
906 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
907 stats->retriesShort ) ||
908 nla_put_u32(vendor_event,
909 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
910 stats->retriesLong ) ||
911 nla_put_u32(vendor_event,
912 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
913 stats->contentionTimeMin ) ||
914 nla_put_u32(vendor_event,
915 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
916 stats->contentionTimeMax ) ||
917 nla_put_u32(vendor_event,
918 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
919 stats->contentionTimeAvg ) ||
920 nla_put_u32(vendor_event,
921 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
922 stats->contentionNumSamples ))
923 {
924 hddLog(VOS_TRACE_LEVEL_ERROR,
925 FL("QCA_WLAN_VENDOR_ATTR put fail") );
926 return FALSE;
927 }
928 return TRUE;
929}
930
931static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
932 struct sk_buff *vendor_event)
933{
Dino Myclec8f3f332014-07-21 16:48:27 +0530934 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530935 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
936 nla_put(vendor_event,
937 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
938 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
939 nla_put_u32(vendor_event,
940 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
941 stats->state ) ||
942 nla_put_u32(vendor_event,
943 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
944 stats->roaming ) ||
945 nla_put_u32(vendor_event,
946 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
947 stats->capabilities ) ||
948 nla_put(vendor_event,
949 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
950 strlen(stats->ssid), stats->ssid) ||
951 nla_put(vendor_event,
952 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
953 WNI_CFG_BSSID_LEN, stats->bssid) ||
954 nla_put(vendor_event,
955 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
956 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
957 nla_put(vendor_event,
958 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
959 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
960 )
961 {
962 hddLog(VOS_TRACE_LEVEL_ERROR,
963 FL("QCA_WLAN_VENDOR_ATTR put fail") );
964 return FALSE;
965 }
966 return TRUE;
967}
968
Dino Mycle3b9536d2014-07-09 22:05:24 +0530969static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
970 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530971 struct sk_buff *vendor_event)
972{
973 int i = 0;
974 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530975 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
976 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530977 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530978
Sunil Duttc69bccb2014-05-26 21:30:20 +0530979 if (FALSE == put_wifi_interface_info(
980 &pWifiIfaceStat->info,
981 vendor_event))
982 {
983 hddLog(VOS_TRACE_LEVEL_ERROR,
984 FL("QCA_WLAN_VENDOR_ATTR put fail") );
985 return FALSE;
986
987 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530988 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
989 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
990 if (NULL == pWifiIfaceStatTL)
991 {
992 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
993 return FALSE;
994 }
995
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530996 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
997 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
998 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
999 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1000
1001 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1002 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1003 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1004 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301005
1006 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1007 {
1008 if (VOS_STATUS_SUCCESS ==
1009 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1010 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1011 {
1012 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1013 * obtained from TL structure
1014 */
1015
1016 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1017 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301018 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1019
Srinivas Dasari98947432014-11-07 19:41:24 +05301020 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1021 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1022 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1023 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1024 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1025 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1026 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1027 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301028
Srinivas Dasari98947432014-11-07 19:41:24 +05301029 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1030 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1031 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1032 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1033 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1034 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1035 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1036 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301037
Srinivas Dasari98947432014-11-07 19:41:24 +05301038 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1039 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1040 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1041 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1042 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1043 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1044 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1045 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301046 }
1047 else
1048 {
1049 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1050 }
1051
Dino Mycle3b9536d2014-07-09 22:05:24 +05301052 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1053 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1054 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1055 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1056 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1057 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1058 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1059 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1060 }
1061 else
1062 {
1063 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1064 }
1065
1066
Sunil Duttc69bccb2014-05-26 21:30:20 +05301067
1068 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301069 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1070 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1071 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301072 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1073 pWifiIfaceStat->beaconRx) ||
1074 nla_put_u32(vendor_event,
1075 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1076 pWifiIfaceStat->mgmtRx) ||
1077 nla_put_u32(vendor_event,
1078 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1079 pWifiIfaceStat->mgmtActionRx) ||
1080 nla_put_u32(vendor_event,
1081 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1082 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301083 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301084 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1085 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301086 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301087 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1088 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301089 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301090 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1091 pWifiIfaceStat->rssiAck))
1092 {
1093 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301094 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1095 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301096 return FALSE;
1097 }
1098
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301099#ifdef FEATURE_EXT_LL_STAT
1100 /*
1101 * Ensure when EXT_LL_STAT is supported by both host and fwr,
1102 * then host should send Leaky AP stats to upper layer,
1103 * otherwise no need to send these stats.
1104 */
1105 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
1106 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
1107 )
1108 {
1109 hddLog(VOS_TRACE_LEVEL_INFO,
1110 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
1111 pWifiIfaceStat->leakyApStat.is_leaky_ap,
1112 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
1113 pWifiIfaceStat->leakyApStat.rx_leak_window,
1114 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
1115 if (nla_put_u32(vendor_event,
1116 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
1117 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
1118 nla_put_u32(vendor_event,
1119 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
1120 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
1121 nla_put_u32(vendor_event,
1122 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
1123 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
1124 nla_put_u64(vendor_event,
1125 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
1126 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
1127 {
1128 hddLog(VOS_TRACE_LEVEL_ERROR,
1129 FL("EXT_LL_STAT put fail"));
1130 vos_mem_free(pWifiIfaceStatTL);
1131 return FALSE;
1132 }
1133 }
1134#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301135 wmmInfo = nla_nest_start(vendor_event,
1136 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301137 if(!wmmInfo)
1138 {
1139 vos_mem_free(pWifiIfaceStatTL);
1140 return FALSE;
1141 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301142 for (i = 0; i < WIFI_AC_MAX; i++)
1143 {
1144 struct nlattr *wmmStats;
1145 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301146 if(!wmmStats)
1147 {
1148 vos_mem_free(pWifiIfaceStatTL);
1149 return FALSE;
1150 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301151 if (FALSE == put_wifi_wmm_ac_stat(
1152 &pWifiIfaceStat->AccessclassStats[i],
1153 vendor_event))
1154 {
1155 hddLog(VOS_TRACE_LEVEL_ERROR,
1156 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301157 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301158 return FALSE;
1159 }
1160
1161 nla_nest_end(vendor_event, wmmStats);
1162 }
1163 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301164 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301165 return TRUE;
1166}
1167
1168static tSirWifiInterfaceMode
1169 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1170{
1171 switch (deviceMode)
1172 {
1173 case WLAN_HDD_INFRA_STATION:
1174 return WIFI_INTERFACE_STA;
1175 case WLAN_HDD_SOFTAP:
1176 return WIFI_INTERFACE_SOFTAP;
1177 case WLAN_HDD_P2P_CLIENT:
1178 return WIFI_INTERFACE_P2P_CLIENT;
1179 case WLAN_HDD_P2P_GO:
1180 return WIFI_INTERFACE_P2P_GO;
1181 case WLAN_HDD_IBSS:
1182 return WIFI_INTERFACE_IBSS;
1183 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301184 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301185 }
1186}
1187
1188static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1189 tpSirWifiInterfaceInfo pInfo)
1190{
1191 v_U8_t *staMac = NULL;
1192 hdd_station_ctx_t *pHddStaCtx;
1193 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1194 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1195
1196 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1197
1198 vos_mem_copy(pInfo->macAddr,
1199 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1200
1201 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1202 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1203 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1204 {
1205 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1206 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1207 {
1208 pInfo->state = WIFI_DISCONNECTED;
1209 }
1210 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1211 {
1212 hddLog(VOS_TRACE_LEVEL_ERROR,
1213 "%s: Session ID %d, Connection is in progress", __func__,
1214 pAdapter->sessionId);
1215 pInfo->state = WIFI_ASSOCIATING;
1216 }
1217 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1218 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1219 {
1220 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1221 hddLog(VOS_TRACE_LEVEL_ERROR,
1222 "%s: client " MAC_ADDRESS_STR
1223 " is in the middle of WPS/EAPOL exchange.", __func__,
1224 MAC_ADDR_ARRAY(staMac));
1225 pInfo->state = WIFI_AUTHENTICATING;
1226 }
1227 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1228 {
1229 pInfo->state = WIFI_ASSOCIATED;
1230 vos_mem_copy(pInfo->bssid,
1231 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1232 vos_mem_copy(pInfo->ssid,
1233 pHddStaCtx->conn_info.SSID.SSID.ssId,
1234 pHddStaCtx->conn_info.SSID.SSID.length);
1235 //NULL Terminate the string.
1236 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1237 }
1238 }
1239 vos_mem_copy(pInfo->countryStr,
1240 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1241
1242 vos_mem_copy(pInfo->apCountryStr,
1243 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1244
1245 return TRUE;
1246}
1247
1248/*
1249 * hdd_link_layer_process_peer_stats () - This function is called after
1250 * receiving Link Layer Peer statistics from FW.This function converts
1251 * the firmware data to the NL data and sends the same to the kernel/upper
1252 * layers.
1253 */
1254static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1255 v_VOID_t *pData)
1256{
1257 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301258 tpSirWifiPeerStat pWifiPeerStat;
1259 tpSirWifiPeerInfo pWifiPeerInfo;
1260 struct nlattr *peerInfo;
1261 struct sk_buff *vendor_event;
1262 int status, i;
1263
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301264 ENTER();
1265
Sunil Duttc69bccb2014-05-26 21:30:20 +05301266 status = wlan_hdd_validate_context(pHddCtx);
1267 if (0 != status)
1268 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301269 return;
1270 }
1271
1272 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1273
1274 hddLog(VOS_TRACE_LEVEL_INFO,
1275 "LL_STATS_PEER_ALL : numPeers %u",
1276 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301277 /*
1278 * Allocate a size of 4096 for the peer stats comprising
1279 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1280 * sizeof (tSirWifiRateStat).Each field is put with an
1281 * NL attribute.The size of 4096 is considered assuming
1282 * that number of rates shall not exceed beyond 50 with
1283 * the sizeof (tSirWifiRateStat) being 32.
1284 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301285 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1286 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301287 if (!vendor_event)
1288 {
1289 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301290 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301291 __func__);
1292 return;
1293 }
1294 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301295 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1296 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1297 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301298 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1299 pWifiPeerStat->numPeers))
1300 {
1301 hddLog(VOS_TRACE_LEVEL_ERROR,
1302 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1303 kfree_skb(vendor_event);
1304 return;
1305 }
1306
1307 peerInfo = nla_nest_start(vendor_event,
1308 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301309 if(!peerInfo)
1310 {
1311 hddLog(VOS_TRACE_LEVEL_ERROR,
1312 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1313 __func__);
1314 kfree_skb(vendor_event);
1315 return;
1316 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301317
1318 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1319 pWifiPeerStat->peerInfo);
1320
1321 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1322 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301323 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301324 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301325
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301326 if(!peers)
1327 {
1328 hddLog(VOS_TRACE_LEVEL_ERROR,
1329 "%s: peer stats put fail",
1330 __func__);
1331 kfree_skb(vendor_event);
1332 return;
1333 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301334 if (FALSE == put_wifi_peer_info(
1335 pWifiPeerInfo, vendor_event))
1336 {
1337 hddLog(VOS_TRACE_LEVEL_ERROR,
1338 "%s: put_wifi_peer_info put fail", __func__);
1339 kfree_skb(vendor_event);
1340 return;
1341 }
1342
1343 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1344 pWifiPeerStat->peerInfo +
1345 (i * sizeof(tSirWifiPeerInfo)) +
1346 (numRate * sizeof (tSirWifiRateStat)));
1347 nla_nest_end(vendor_event, peers);
1348 }
1349 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301350 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301351 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301352}
1353
1354/*
1355 * hdd_link_layer_process_iface_stats () - This function is called after
1356 * receiving Link Layer Interface statistics from FW.This function converts
1357 * the firmware data to the NL data and sends the same to the kernel/upper
1358 * layers.
1359 */
1360static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1361 v_VOID_t *pData)
1362{
1363 tpSirWifiIfaceStat pWifiIfaceStat;
1364 struct sk_buff *vendor_event;
1365 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1366 int status;
1367
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301368 ENTER();
1369
Sunil Duttc69bccb2014-05-26 21:30:20 +05301370 status = wlan_hdd_validate_context(pHddCtx);
1371 if (0 != status)
1372 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301373 return;
1374 }
1375 /*
1376 * Allocate a size of 4096 for the interface stats comprising
1377 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1378 * assuming that all these fit with in the limit.Please take
1379 * a call on the limit based on the data requirements on
1380 * interface statistics.
1381 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301382 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1383 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301384 if (!vendor_event)
1385 {
1386 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301387 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301388 return;
1389 }
1390
1391 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1392
Dino Mycle3b9536d2014-07-09 22:05:24 +05301393
1394 if (FALSE == hdd_get_interface_info( pAdapter,
1395 &pWifiIfaceStat->info))
1396 {
1397 hddLog(VOS_TRACE_LEVEL_ERROR,
1398 FL("hdd_get_interface_info get fail") );
1399 kfree_skb(vendor_event);
1400 return;
1401 }
1402
1403 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1404 vendor_event))
1405 {
1406 hddLog(VOS_TRACE_LEVEL_ERROR,
1407 FL("put_wifi_iface_stats fail") );
1408 kfree_skb(vendor_event);
1409 return;
1410 }
1411
Sunil Duttc69bccb2014-05-26 21:30:20 +05301412 hddLog(VOS_TRACE_LEVEL_INFO,
1413 "WMI_LINK_STATS_IFACE Data");
1414
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301415 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301416
1417 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301418}
1419
1420/*
1421 * hdd_link_layer_process_radio_stats () - This function is called after
1422 * receiving Link Layer Radio statistics from FW.This function converts
1423 * the firmware data to the NL data and sends the same to the kernel/upper
1424 * layers.
1425 */
1426static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1427 v_VOID_t *pData)
1428{
1429 int status, i;
1430 tpSirWifiRadioStat pWifiRadioStat;
1431 tpSirWifiChannelStats pWifiChannelStats;
1432 struct sk_buff *vendor_event;
1433 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1434 struct nlattr *chList;
1435
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301436 ENTER();
1437
Sunil Duttc69bccb2014-05-26 21:30:20 +05301438 status = wlan_hdd_validate_context(pHddCtx);
1439 if (0 != status)
1440 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301441 return;
1442 }
1443 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1444
1445 hddLog(VOS_TRACE_LEVEL_INFO,
1446 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301447 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05301448 " radio is %d onTime is %u "
1449 " txTime is %u rxTime is %u "
1450 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301451 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301452 " onTimePnoScan is %u onTimeHs20 is %u "
1453 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301454 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301455 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1456 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1457 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301458 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301459 pWifiRadioStat->onTimeRoamScan,
1460 pWifiRadioStat->onTimePnoScan,
1461 pWifiRadioStat->onTimeHs20,
1462 pWifiRadioStat->numChannels);
1463 /*
1464 * Allocate a size of 4096 for the Radio stats comprising
1465 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1466 * (tSirWifiChannelStats).Each channel data is put with an
1467 * NL attribute.The size of 4096 is considered assuming that
1468 * number of channels shall not exceed beyond 60 with the
1469 * sizeof (tSirWifiChannelStats) being 24 bytes.
1470 */
1471
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301472 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1473 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301474 if (!vendor_event)
1475 {
1476 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301477 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301478 return;
1479 }
1480
1481 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301482 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1483 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1484 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301485 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1486 pWifiRadioStat->radio) ||
1487 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301488 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
1489 NUM_RADIOS) ||
1490 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301491 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1492 pWifiRadioStat->onTime) ||
1493 nla_put_u32(vendor_event,
1494 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1495 pWifiRadioStat->txTime) ||
1496 nla_put_u32(vendor_event,
1497 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1498 pWifiRadioStat->rxTime) ||
1499 nla_put_u32(vendor_event,
1500 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1501 pWifiRadioStat->onTimeScan) ||
1502 nla_put_u32(vendor_event,
1503 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1504 pWifiRadioStat->onTimeNbd) ||
1505 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301506 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1507 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301508 nla_put_u32(vendor_event,
1509 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1510 pWifiRadioStat->onTimeRoamScan) ||
1511 nla_put_u32(vendor_event,
1512 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1513 pWifiRadioStat->onTimePnoScan) ||
1514 nla_put_u32(vendor_event,
1515 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1516 pWifiRadioStat->onTimeHs20) ||
1517 nla_put_u32(vendor_event,
1518 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1519 pWifiRadioStat->numChannels))
1520 {
1521 hddLog(VOS_TRACE_LEVEL_ERROR,
1522 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1523 kfree_skb(vendor_event);
1524 return ;
1525 }
1526
1527 chList = nla_nest_start(vendor_event,
1528 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301529 if(!chList)
1530 {
1531 hddLog(VOS_TRACE_LEVEL_ERROR,
1532 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1533 __func__);
1534 kfree_skb(vendor_event);
1535 return;
1536 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301537 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1538 {
1539 struct nlattr *chInfo;
1540
1541 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1542 pWifiRadioStat->channels +
1543 (i * sizeof(tSirWifiChannelStats)));
1544
Sunil Duttc69bccb2014-05-26 21:30:20 +05301545 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301546 if(!chInfo)
1547 {
1548 hddLog(VOS_TRACE_LEVEL_ERROR,
1549 "%s: failed to put chInfo",
1550 __func__);
1551 kfree_skb(vendor_event);
1552 return;
1553 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301554
1555 if (nla_put_u32(vendor_event,
1556 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1557 pWifiChannelStats->channel.width) ||
1558 nla_put_u32(vendor_event,
1559 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1560 pWifiChannelStats->channel.centerFreq) ||
1561 nla_put_u32(vendor_event,
1562 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1563 pWifiChannelStats->channel.centerFreq0) ||
1564 nla_put_u32(vendor_event,
1565 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1566 pWifiChannelStats->channel.centerFreq1) ||
1567 nla_put_u32(vendor_event,
1568 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1569 pWifiChannelStats->onTime) ||
1570 nla_put_u32(vendor_event,
1571 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1572 pWifiChannelStats->ccaBusyTime))
1573 {
1574 hddLog(VOS_TRACE_LEVEL_ERROR,
1575 FL("cfg80211_vendor_event_alloc failed") );
1576 kfree_skb(vendor_event);
1577 return ;
1578 }
1579 nla_nest_end(vendor_event, chInfo);
1580 }
1581 nla_nest_end(vendor_event, chList);
1582
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301583 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301584
1585 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301586 return;
1587}
1588
1589/*
1590 * hdd_link_layer_stats_ind_callback () - This function is called after
1591 * receiving Link Layer indications from FW.This callback converts the firmware
1592 * data to the NL data and send the same to the kernel/upper layers.
1593 */
1594static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1595 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301596 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301597{
Dino Mycled3d50022014-07-07 12:58:25 +05301598 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1599 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301600 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301601 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301602 int status;
1603
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301604 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301605
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301606 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301607 if (0 != status)
1608 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301609 return;
1610 }
1611
Dino Mycled3d50022014-07-07 12:58:25 +05301612 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1613 if (NULL == pAdapter)
1614 {
1615 hddLog(VOS_TRACE_LEVEL_ERROR,
1616 FL(" MAC address %pM does not exist with host"),
1617 macAddr);
1618 return;
1619 }
1620
Sunil Duttc69bccb2014-05-26 21:30:20 +05301621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301622 "%s: Interface: %s LLStats indType: %d", __func__,
1623 pAdapter->dev->name, indType);
1624
Sunil Duttc69bccb2014-05-26 21:30:20 +05301625 switch (indType)
1626 {
1627 case SIR_HAL_LL_STATS_RESULTS_RSP:
1628 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301629 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301630 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1631 "respId = %u, moreResultToFollow = %u",
1632 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1633 macAddr, linkLayerStatsResults->respId,
1634 linkLayerStatsResults->moreResultToFollow);
1635
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301636 spin_lock(&hdd_context_lock);
1637 context = &pHddCtx->ll_stats_context;
1638 /* validate response received from target */
1639 if ((context->request_id != linkLayerStatsResults->respId) ||
1640 !(context->request_bitmap & linkLayerStatsResults->paramId))
1641 {
1642 spin_unlock(&hdd_context_lock);
1643 hddLog(LOGE,
1644 FL("Error : Request id %d response id %d request bitmap 0x%x"
1645 "response bitmap 0x%x"),
1646 context->request_id, linkLayerStatsResults->respId,
1647 context->request_bitmap, linkLayerStatsResults->paramId);
1648 return;
1649 }
1650 spin_unlock(&hdd_context_lock);
1651
Sunil Duttc69bccb2014-05-26 21:30:20 +05301652 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1653 {
1654 hdd_link_layer_process_radio_stats(pAdapter,
1655 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301656 spin_lock(&hdd_context_lock);
1657 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1658 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301659 }
1660 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1661 {
1662 hdd_link_layer_process_iface_stats(pAdapter,
1663 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301664 spin_lock(&hdd_context_lock);
1665 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1666 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301667 }
1668 else if ( linkLayerStatsResults->paramId &
1669 WMI_LINK_STATS_ALL_PEER )
1670 {
1671 hdd_link_layer_process_peer_stats(pAdapter,
1672 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301673 spin_lock(&hdd_context_lock);
1674 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1675 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301676 } /* WMI_LINK_STATS_ALL_PEER */
1677 else
1678 {
1679 hddLog(VOS_TRACE_LEVEL_ERROR,
1680 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1681 }
1682
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301683 spin_lock(&hdd_context_lock);
1684 /* complete response event if all requests are completed */
1685 if (0 == context->request_bitmap)
1686 complete(&context->response_event);
1687 spin_unlock(&hdd_context_lock);
1688
Sunil Duttc69bccb2014-05-26 21:30:20 +05301689 break;
1690 }
1691 default:
1692 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1693 break;
1694 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301695
1696 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301697 return;
1698}
1699
1700const struct
1701nla_policy
1702qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1703{
1704 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1705 { .type = NLA_U32 },
1706 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1707 { .type = NLA_U32 },
1708};
1709
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301710static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1711 struct wireless_dev *wdev,
1712 const void *data,
1713 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301714{
1715 int status;
1716 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301717 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301718 struct net_device *dev = wdev->netdev;
1719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1720 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1721
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301722 ENTER();
1723
Sunil Duttc69bccb2014-05-26 21:30:20 +05301724 status = wlan_hdd_validate_context(pHddCtx);
1725 if (0 != status)
1726 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301727 return -EINVAL;
1728 }
1729
1730 if (NULL == pAdapter)
1731 {
1732 hddLog(VOS_TRACE_LEVEL_ERROR,
1733 FL("HDD adapter is Null"));
1734 return -ENODEV;
1735 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301736 /* check the LLStats Capability */
1737 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1738 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1739 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05301740 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301741 FL("Link Layer Statistics not supported by Firmware"));
1742 return -EINVAL;
1743 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301744
1745 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1746 (struct nlattr *)data,
1747 data_len, qca_wlan_vendor_ll_set_policy))
1748 {
1749 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1750 return -EINVAL;
1751 }
1752 if (!tb_vendor
1753 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1754 {
1755 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1756 return -EINVAL;
1757 }
1758 if (!tb_vendor[
1759 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1760 {
1761 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1762 return -EINVAL;
1763 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301764 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301765 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301766
Dino Mycledf0a5d92014-07-04 09:41:55 +05301767 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301768 nla_get_u32(
1769 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1770
Dino Mycledf0a5d92014-07-04 09:41:55 +05301771 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301772 nla_get_u32(
1773 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1774
Dino Mycled3d50022014-07-07 12:58:25 +05301775 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1776 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301777
1778
1779 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301780 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1781 "Statistics Gathering = %d ",
1782 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1783 linkLayerStatsSetReq.mpduSizeThreshold,
1784 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301785
1786 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1787 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301788 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301789 {
1790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1791 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301792 return -EINVAL;
1793
1794 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301795
Sunil Duttc69bccb2014-05-26 21:30:20 +05301796 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301797 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301798 {
1799 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1800 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301801 return -EINVAL;
1802 }
1803
1804 pAdapter->isLinkLayerStatsSet = 1;
1805
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301806 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301807 return 0;
1808}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301809static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1810 struct wireless_dev *wdev,
1811 const void *data,
1812 int data_len)
1813{
1814 int ret = 0;
1815
1816 vos_ssr_protect(__func__);
1817 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1818 vos_ssr_unprotect(__func__);
1819
1820 return ret;
1821}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301822
1823const struct
1824nla_policy
1825qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1826{
1827 /* Unsigned 32bit value provided by the caller issuing the GET stats
1828 * command. When reporting
1829 * the stats results, the driver uses the same value to indicate
1830 * which GET request the results
1831 * correspond to.
1832 */
1833 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1834
1835 /* Unsigned 32bit value . bit mask to identify what statistics are
1836 requested for retrieval */
1837 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1838};
1839
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301840static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1841 struct wireless_dev *wdev,
1842 const void *data,
1843 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301844{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301845 unsigned long rc;
1846 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301847 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1848 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301849 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301850 struct net_device *dev = wdev->netdev;
1851 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301852 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301853 int status;
1854
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301855 ENTER();
1856
Sunil Duttc69bccb2014-05-26 21:30:20 +05301857 status = wlan_hdd_validate_context(pHddCtx);
1858 if (0 != status)
1859 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301860 return -EINVAL ;
1861 }
1862
1863 if (NULL == pAdapter)
1864 {
1865 hddLog(VOS_TRACE_LEVEL_FATAL,
1866 "%s: HDD adapter is Null", __func__);
1867 return -ENODEV;
1868 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301869
1870 if (pHddStaCtx == NULL)
1871 {
1872 hddLog(VOS_TRACE_LEVEL_FATAL,
1873 "%s: HddStaCtx is Null", __func__);
1874 return -ENODEV;
1875 }
1876
Dino Mycledf0a5d92014-07-04 09:41:55 +05301877 /* check the LLStats Capability */
1878 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1879 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1880 {
1881 hddLog(VOS_TRACE_LEVEL_ERROR,
1882 FL("Link Layer Statistics not supported by Firmware"));
1883 return -EINVAL;
1884 }
1885
Sunil Duttc69bccb2014-05-26 21:30:20 +05301886
1887 if (!pAdapter->isLinkLayerStatsSet)
1888 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05301889 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301890 "%s: isLinkLayerStatsSet : %d",
1891 __func__, pAdapter->isLinkLayerStatsSet);
1892 return -EINVAL;
1893 }
1894
Mukul Sharma10313ba2015-07-29 19:14:39 +05301895 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1896 {
1897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1898 "%s: Roaming in progress, so unable to proceed this request", __func__);
1899 return -EBUSY;
1900 }
1901
Sunil Duttc69bccb2014-05-26 21:30:20 +05301902 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1903 (struct nlattr *)data,
1904 data_len, qca_wlan_vendor_ll_get_policy))
1905 {
1906 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1907 return -EINVAL;
1908 }
1909
1910 if (!tb_vendor
1911 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1912 {
1913 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1914 return -EINVAL;
1915 }
1916
1917 if (!tb_vendor
1918 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1919 {
1920 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1921 return -EINVAL;
1922 }
1923
Sunil Duttc69bccb2014-05-26 21:30:20 +05301924
Dino Mycledf0a5d92014-07-04 09:41:55 +05301925 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301926 nla_get_u32( tb_vendor[
1927 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301928 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301929 nla_get_u32( tb_vendor[
1930 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1931
Dino Mycled3d50022014-07-07 12:58:25 +05301932 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1933 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301934
1935 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301936 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1937 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301938 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301939
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301940 spin_lock(&hdd_context_lock);
1941 context = &pHddCtx->ll_stats_context;
1942 context->request_id = linkLayerStatsGetReq.reqId;
1943 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1944 INIT_COMPLETION(context->response_event);
1945 spin_unlock(&hdd_context_lock);
1946
Sunil Duttc69bccb2014-05-26 21:30:20 +05301947 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301948 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301949 {
1950 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1951 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301952 return -EINVAL;
1953 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301954
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301955 rc = wait_for_completion_timeout(&context->response_event,
1956 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1957 if (!rc)
1958 {
1959 hddLog(LOGE,
1960 FL("Target response timed out request id %d request bitmap 0x%x"),
1961 context->request_id, context->request_bitmap);
1962 return -ETIMEDOUT;
1963 }
1964
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301965 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301966 return 0;
1967}
1968
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301969static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1970 struct wireless_dev *wdev,
1971 const void *data,
1972 int data_len)
1973{
1974 int ret = 0;
1975
1976 vos_ssr_protect(__func__);
1977 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1978 vos_ssr_unprotect(__func__);
1979
1980 return ret;
1981}
1982
Sunil Duttc69bccb2014-05-26 21:30:20 +05301983const struct
1984nla_policy
1985qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1986{
1987 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1988 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1989 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1990 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1991};
1992
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301993static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1994 struct wireless_dev *wdev,
1995 const void *data,
1996 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301997{
1998 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1999 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302000 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302001 struct net_device *dev = wdev->netdev;
2002 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2003 u32 statsClearReqMask;
2004 u8 stopReq;
2005 int status;
2006
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302007 ENTER();
2008
Sunil Duttc69bccb2014-05-26 21:30:20 +05302009 status = wlan_hdd_validate_context(pHddCtx);
2010 if (0 != status)
2011 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302012 return -EINVAL;
2013 }
2014
2015 if (NULL == pAdapter)
2016 {
2017 hddLog(VOS_TRACE_LEVEL_FATAL,
2018 "%s: HDD adapter is Null", __func__);
2019 return -ENODEV;
2020 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302021 /* check the LLStats Capability */
2022 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2023 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2024 {
2025 hddLog(VOS_TRACE_LEVEL_ERROR,
2026 FL("Enable LLStats Capability"));
2027 return -EINVAL;
2028 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302029
2030 if (!pAdapter->isLinkLayerStatsSet)
2031 {
2032 hddLog(VOS_TRACE_LEVEL_FATAL,
2033 "%s: isLinkLayerStatsSet : %d",
2034 __func__, pAdapter->isLinkLayerStatsSet);
2035 return -EINVAL;
2036 }
2037
2038 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2039 (struct nlattr *)data,
2040 data_len, qca_wlan_vendor_ll_clr_policy))
2041 {
2042 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2043 return -EINVAL;
2044 }
2045
2046 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2047
2048 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2049 {
2050 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2051 return -EINVAL;
2052
2053 }
2054
Sunil Duttc69bccb2014-05-26 21:30:20 +05302055
Dino Mycledf0a5d92014-07-04 09:41:55 +05302056 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302057 nla_get_u32(
2058 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2059
Dino Mycledf0a5d92014-07-04 09:41:55 +05302060 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302061 nla_get_u8(
2062 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2063
2064 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302065 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302066
Dino Mycled3d50022014-07-07 12:58:25 +05302067 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2068 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302069
2070 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302071 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2072 "statsClearReqMask = 0x%X, stopReq = %d",
2073 linkLayerStatsClearReq.reqId,
2074 linkLayerStatsClearReq.macAddr,
2075 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302076 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302077
2078 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302079 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302080 {
2081 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302082 hdd_station_ctx_t *pHddStaCtx;
2083
2084 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2085 if (VOS_STATUS_SUCCESS !=
2086 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2087 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2088 {
2089 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2090 "WLANTL_ClearInterfaceStats Failed", __func__);
2091 return -EINVAL;
2092 }
2093 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2094 (statsClearReqMask & WIFI_STATS_IFACE)) {
2095 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2096 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2097 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2098 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2099 }
2100
Sunil Duttc69bccb2014-05-26 21:30:20 +05302101 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2102 2 * sizeof(u32) +
2103 NLMSG_HDRLEN);
2104
2105 if (temp_skbuff != NULL)
2106 {
2107
2108 if (nla_put_u32(temp_skbuff,
2109 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2110 statsClearReqMask) ||
2111 nla_put_u32(temp_skbuff,
2112 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2113 stopReq))
2114 {
2115 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2116 kfree_skb(temp_skbuff);
2117 return -EINVAL;
2118 }
2119 /* If the ask is to stop the stats collection as part of clear
2120 * (stopReq = 1) , ensure that no further requests of get
2121 * go to the firmware by having isLinkLayerStatsSet set to 0.
2122 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302123 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302124 * case the firmware is just asked to clear the statistics.
2125 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302126 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302127 pAdapter->isLinkLayerStatsSet = 0;
2128 return cfg80211_vendor_cmd_reply(temp_skbuff);
2129 }
2130 return -ENOMEM;
2131 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302132
2133 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302134 return -EINVAL;
2135}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302136static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2137 struct wireless_dev *wdev,
2138 const void *data,
2139 int data_len)
2140{
2141 int ret = 0;
2142
2143 vos_ssr_protect(__func__);
2144 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2145 vos_ssr_unprotect(__func__);
2146
2147 return ret;
2148
2149
2150}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302151#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2152
Dino Mycle6fb96c12014-06-10 11:52:40 +05302153#ifdef WLAN_FEATURE_EXTSCAN
2154static const struct nla_policy
2155wlan_hdd_extscan_config_policy
2156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2157{
2158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2159 { .type = NLA_U32 },
2160 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2161 { .type = NLA_U32 },
2162 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2163 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2164 { .type = NLA_U32 },
2165 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2166 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2167
2168 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2169 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2170 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2171 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2172 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302173 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2174 { .type = NLA_U32 },
2175 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2176 { .type = NLA_U32 },
2177 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2178 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302179 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2180 { .type = NLA_U32 },
2181 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2182 { .type = NLA_U32 },
2183 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2184 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302185 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2186 { .type = NLA_U8 },
2187 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302188 { .type = NLA_U8 },
2189 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2190 { .type = NLA_U8 },
2191 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2192 { .type = NLA_U8 },
2193
2194 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2195 { .type = NLA_U32 },
2196 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2197 { .type = NLA_UNSPEC },
2198 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2199 { .type = NLA_S32 },
2200 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2201 { .type = NLA_S32 },
2202 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2203 { .type = NLA_U32 },
2204 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2205 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302206 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2207 { .type = NLA_U32 },
2208 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2209 { .type = NLA_BINARY,
2210 .len = IEEE80211_MAX_SSID_LEN + 1 },
2211 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302212 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302213 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2214 { .type = NLA_U32 },
2215 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2216 { .type = NLA_U8 },
2217 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2218 { .type = NLA_S32 },
2219 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2220 { .type = NLA_S32 },
2221 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2222 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302223};
2224
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302225/**
2226 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2227 * @ctx: hdd global context
2228 * @data: capabilities data
2229 *
2230 * Return: none
2231 */
2232static void
2233wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302234{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302235 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302236 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302237 tSirEXTScanCapabilitiesEvent *data =
2238 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302239
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302240 ENTER();
2241
2242 if (wlan_hdd_validate_context(pHddCtx))
2243 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302244 return;
2245 }
2246
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302247 if (!pMsg)
2248 {
2249 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2250 return;
2251 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302252
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302253 vos_spin_lock_acquire(&hdd_context_lock);
2254
2255 context = &pHddCtx->ext_scan_context;
2256 /* validate response received from target*/
2257 if (context->request_id != data->requestId)
2258 {
2259 vos_spin_lock_release(&hdd_context_lock);
2260 hddLog(LOGE,
2261 FL("Target response id did not match: request_id %d resposne_id %d"),
2262 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302263 return;
2264 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302265 else
2266 {
2267 context->capability_response = *data;
2268 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302269 }
2270
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302271 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302272
Dino Mycle6fb96c12014-06-10 11:52:40 +05302273 return;
2274}
2275
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302276/*
2277 * define short names for the global vendor params
2278 * used by wlan_hdd_send_ext_scan_capability()
2279 */
2280#define PARAM_REQUEST_ID \
2281 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2282#define PARAM_STATUS \
2283 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2284#define MAX_SCAN_CACHE_SIZE \
2285 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2286#define MAX_SCAN_BUCKETS \
2287 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2288#define MAX_AP_CACHE_PER_SCAN \
2289 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2290#define MAX_RSSI_SAMPLE_SIZE \
2291 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2292#define MAX_SCAN_RPT_THRHOLD \
2293 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2294#define MAX_HOTLIST_BSSIDS \
2295 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2296#define MAX_BSSID_HISTORY_ENTRIES \
2297 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2298#define MAX_HOTLIST_SSIDS \
2299 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302300#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2301 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302302
2303static int wlan_hdd_send_ext_scan_capability(void *ctx)
2304{
2305 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2306 struct sk_buff *skb = NULL;
2307 int ret;
2308 tSirEXTScanCapabilitiesEvent *data;
2309 tANI_U32 nl_buf_len;
2310
2311 ret = wlan_hdd_validate_context(pHddCtx);
2312 if (0 != ret)
2313 {
2314 return ret;
2315 }
2316
2317 data = &(pHddCtx->ext_scan_context.capability_response);
2318
2319 nl_buf_len = NLMSG_HDRLEN;
2320 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2321 (sizeof(data->status) + NLA_HDRLEN) +
2322 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2323 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2324 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2325 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2326 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2327 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2328 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2329 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2330
2331 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2332
2333 if (!skb)
2334 {
2335 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2336 return -ENOMEM;
2337 }
2338
2339 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2340 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2341 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2342 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2343 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2344 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2345 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2346 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2347
2348 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2349 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2350 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2351 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2352 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2353 data->maxApPerScan) ||
2354 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2355 data->maxRssiSampleSize) ||
2356 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2357 data->maxScanReportingThreshold) ||
2358 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2359 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2360 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302361 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2362 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302363 {
2364 hddLog(LOGE, FL("nla put fail"));
2365 goto nla_put_failure;
2366 }
2367
2368 cfg80211_vendor_cmd_reply(skb);
2369 return 0;
2370
2371nla_put_failure:
2372 kfree_skb(skb);
2373 return -EINVAL;;
2374}
2375
2376/*
2377 * done with short names for the global vendor params
2378 * used by wlan_hdd_send_ext_scan_capability()
2379 */
2380#undef PARAM_REQUEST_ID
2381#undef PARAM_STATUS
2382#undef MAX_SCAN_CACHE_SIZE
2383#undef MAX_SCAN_BUCKETS
2384#undef MAX_AP_CACHE_PER_SCAN
2385#undef MAX_RSSI_SAMPLE_SIZE
2386#undef MAX_SCAN_RPT_THRHOLD
2387#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302388#undef MAX_BSSID_HISTORY_ENTRIES
2389#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302390
2391static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2392{
2393 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2394 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302395 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302396 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302397
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302398 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302399
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302400 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302401 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302402
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302403 if (!pMsg)
2404 {
2405 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302406 return;
2407 }
2408
Dino Mycle6fb96c12014-06-10 11:52:40 +05302409 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2410 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2411
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302412 context = &pHddCtx->ext_scan_context;
2413 spin_lock(&hdd_context_lock);
2414 if (context->request_id == pData->requestId) {
2415 context->response_status = pData->status ? -EINVAL : 0;
2416 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302417 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302418 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302419
2420 /*
2421 * Store the Request ID for comparing with the requestID obtained
2422 * in other requests.HDD shall return a failure is the extscan_stop
2423 * request is issued with a different requestId as that of the
2424 * extscan_start request. Also, This requestId shall be used while
2425 * indicating the full scan results to the upper layers.
2426 * The requestId is stored with the assumption that the firmware
2427 * shall return the ext scan start request's requestId in ext scan
2428 * start response.
2429 */
2430 if (pData->status == 0)
2431 pMac->sme.extScanStartReqId = pData->requestId;
2432
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302433 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302434 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302435}
2436
2437
2438static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2439{
2440 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2441 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302442 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302443
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302444 ENTER();
2445
2446 if (wlan_hdd_validate_context(pHddCtx)){
2447 return;
2448 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302449
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302450 if (!pMsg)
2451 {
2452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302453 return;
2454 }
2455
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302456 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2457 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302458
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302459 context = &pHddCtx->ext_scan_context;
2460 spin_lock(&hdd_context_lock);
2461 if (context->request_id == pData->requestId) {
2462 context->response_status = pData->status ? -EINVAL : 0;
2463 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302464 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302465 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302466
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302467 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302468 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302469}
2470
Dino Mycle6fb96c12014-06-10 11:52:40 +05302471static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2472 void *pMsg)
2473{
2474 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302475 tpSirEXTScanSetBssidHotListRspParams pData =
2476 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302477 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302478
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302479 ENTER();
2480
2481 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302482 return;
2483 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302484
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302485 if (!pMsg)
2486 {
2487 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2488 return;
2489 }
2490
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302491 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2492 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302493
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302494 context = &pHddCtx->ext_scan_context;
2495 spin_lock(&hdd_context_lock);
2496 if (context->request_id == pData->requestId) {
2497 context->response_status = pData->status ? -EINVAL : 0;
2498 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302499 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302500 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302501
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302502 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302503 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302504}
2505
2506static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2507 void *pMsg)
2508{
2509 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302510 tpSirEXTScanResetBssidHotlistRspParams pData =
2511 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302512 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302513
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302514 ENTER();
2515
2516 if (wlan_hdd_validate_context(pHddCtx)) {
2517 return;
2518 }
2519 if (!pMsg)
2520 {
2521 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302522 return;
2523 }
2524
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302525 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2526 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302527
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302528 context = &pHddCtx->ext_scan_context;
2529 spin_lock(&hdd_context_lock);
2530 if (context->request_id == pData->requestId) {
2531 context->response_status = pData->status ? -EINVAL : 0;
2532 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302533 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302534 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302535
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302536 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302537 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302538}
2539
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302540static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2541 void *pMsg)
2542{
2543 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2544 tpSirEXTScanSetSsidHotListRspParams pData =
2545 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2546 struct hdd_ext_scan_context *context;
2547
2548 if (wlan_hdd_validate_context(pHddCtx)){
2549 return;
2550 }
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
2572static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2573 void *pMsg)
2574{
2575 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2576 tpSirEXTScanResetSsidHotlistRspParams pData =
2577 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2578 struct hdd_ext_scan_context *context;
2579
2580 if (wlan_hdd_validate_context(pHddCtx)) {
2581 return;
2582 }
2583 if (!pMsg)
2584 {
2585 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2586 return;
2587 }
2588
2589 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2590 pData->status);
2591
2592 context = &pHddCtx->ext_scan_context;
2593 spin_lock(&hdd_context_lock);
2594 if (context->request_id == pData->requestId) {
2595 context->response_status = pData->status ? -EINVAL : 0;
2596 complete(&context->response_event);
2597 }
2598 spin_unlock(&hdd_context_lock);
2599
2600 return;
2601}
2602
2603
Dino Mycle6fb96c12014-06-10 11:52:40 +05302604static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2605 void *pMsg)
2606{
2607 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2608 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302609 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302610 tANI_S32 totalResults;
2611 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302612 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2613 struct hdd_ext_scan_context *context;
2614 bool ignore_cached_results = false;
2615 tExtscanCachedScanResult *result;
2616 struct nlattr *nla_results;
2617 tANI_U16 ieLength= 0;
2618 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302619
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302620 ENTER();
2621
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302622 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302623 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302624
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302625 if (!pMsg)
2626 {
2627 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2628 return;
2629 }
2630
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302631 spin_lock(&hdd_context_lock);
2632 context = &pHddCtx->ext_scan_context;
2633 ignore_cached_results = context->ignore_cached_results;
2634 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302635
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302636 if (ignore_cached_results) {
2637 hddLog(LOGE,
2638 FL("Ignore the cached results received after timeout"));
2639 return;
2640 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302641
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302642 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2643 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302644
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302645 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302646
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302647 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2648 scan_id_index++) {
2649 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302650
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302651 totalResults = result->num_results;
2652 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2653 result->scan_id, result->flags, totalResults);
2654 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302655
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302656 do{
2657 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2658 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2659 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302660
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302661 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2662 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2663
2664 if (!skb) {
2665 hddLog(VOS_TRACE_LEVEL_ERROR,
2666 FL("cfg80211_vendor_event_alloc failed"));
2667 return;
2668 }
2669
2670 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2671
2672 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2673 pData->requestId) ||
2674 nla_put_u32(skb,
2675 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2676 resultsPerEvent)) {
2677 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2678 goto fail;
2679 }
2680 if (nla_put_u8(skb,
2681 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2682 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302683 {
2684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2685 goto fail;
2686 }
2687
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302688 if (nla_put_u32(skb,
2689 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2690 result->scan_id)) {
2691 hddLog(LOGE, FL("put fail"));
2692 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302693 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302694
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302695 nla_results = nla_nest_start(skb,
2696 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2697 if (!nla_results)
2698 goto fail;
2699
2700 if (resultsPerEvent) {
2701 struct nlattr *aps;
2702 struct nlattr *nla_result;
2703
2704 nla_result = nla_nest_start(skb, scan_id_index);
2705 if(!nla_result)
2706 goto fail;
2707
2708 if (nla_put_u32(skb,
2709 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2710 result->scan_id) ||
2711 nla_put_u32(skb,
2712 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2713 result->flags) ||
2714 nla_put_u32(skb,
2715 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2716 totalResults)) {
2717 hddLog(LOGE, FL("put fail"));
2718 goto fail;
2719 }
2720
2721 aps = nla_nest_start(skb,
2722 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2723 if (!aps)
2724 {
2725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2726 goto fail;
2727 }
2728
2729 head_ptr = (tpSirWifiScanResult) &(result->ap);
2730
2731 for (j = 0; j < resultsPerEvent; j++, i++) {
2732 struct nlattr *ap;
2733 pSirWifiScanResult = head_ptr + i;
2734
2735 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05302736 * Firmware returns timestamp from extscan_start till
2737 * BSSID was cached (in micro seconds). Add this with
2738 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302739 * to derive the time since boot when the
2740 * BSSID was cached.
2741 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05302742 pSirWifiScanResult->ts +=
2743 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302744 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2745 "Ssid (%s)"
2746 "Bssid: %pM "
2747 "Channel (%u)"
2748 "Rssi (%d)"
2749 "RTT (%u)"
2750 "RTT_SD (%u)"
2751 "Beacon Period %u"
2752 "Capability 0x%x "
2753 "Ie length %d",
2754 i,
2755 pSirWifiScanResult->ts,
2756 pSirWifiScanResult->ssid,
2757 pSirWifiScanResult->bssid,
2758 pSirWifiScanResult->channel,
2759 pSirWifiScanResult->rssi,
2760 pSirWifiScanResult->rtt,
2761 pSirWifiScanResult->rtt_sd,
2762 pSirWifiScanResult->beaconPeriod,
2763 pSirWifiScanResult->capability,
2764 ieLength);
2765
2766 ap = nla_nest_start(skb, j + 1);
2767 if (!ap)
2768 {
2769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2770 goto fail;
2771 }
2772
2773 if (nla_put_u64(skb,
2774 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2775 pSirWifiScanResult->ts) )
2776 {
2777 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2778 goto fail;
2779 }
2780 if (nla_put(skb,
2781 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2782 sizeof(pSirWifiScanResult->ssid),
2783 pSirWifiScanResult->ssid) )
2784 {
2785 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2786 goto fail;
2787 }
2788 if (nla_put(skb,
2789 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2790 sizeof(pSirWifiScanResult->bssid),
2791 pSirWifiScanResult->bssid) )
2792 {
2793 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2794 goto fail;
2795 }
2796 if (nla_put_u32(skb,
2797 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2798 pSirWifiScanResult->channel) )
2799 {
2800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2801 goto fail;
2802 }
2803 if (nla_put_s32(skb,
2804 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2805 pSirWifiScanResult->rssi) )
2806 {
2807 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2808 goto fail;
2809 }
2810 if (nla_put_u32(skb,
2811 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2812 pSirWifiScanResult->rtt) )
2813 {
2814 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2815 goto fail;
2816 }
2817 if (nla_put_u32(skb,
2818 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2819 pSirWifiScanResult->rtt_sd))
2820 {
2821 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2822 goto fail;
2823 }
2824 if (nla_put_u32(skb,
2825 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2826 pSirWifiScanResult->beaconPeriod))
2827 {
2828 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2829 goto fail;
2830 }
2831 if (nla_put_u32(skb,
2832 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2833 pSirWifiScanResult->capability))
2834 {
2835 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2836 goto fail;
2837 }
2838 if (nla_put_u32(skb,
2839 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2840 ieLength))
2841 {
2842 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2843 goto fail;
2844 }
2845
2846 if (ieLength)
2847 if (nla_put(skb,
2848 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2849 ieLength, ie)) {
2850 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2851 goto fail;
2852 }
2853
2854 nla_nest_end(skb, ap);
2855 }
2856 nla_nest_end(skb, aps);
2857 nla_nest_end(skb, nla_result);
2858 }
2859
2860 nla_nest_end(skb, nla_results);
2861
2862 cfg80211_vendor_cmd_reply(skb);
2863
2864 } while (totalResults > 0);
2865 }
2866
2867 if (!pData->moreData) {
2868 spin_lock(&hdd_context_lock);
2869 context->response_status = 0;
2870 complete(&context->response_event);
2871 spin_unlock(&hdd_context_lock);
2872 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302873
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302874 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302875 return;
2876fail:
2877 kfree_skb(skb);
2878 return;
2879}
2880
2881static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2882 void *pMsg)
2883{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302884 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302885 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2886 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302887 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302888
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302889 ENTER();
2890
2891 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302892 hddLog(LOGE,
2893 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302894 return;
2895 }
2896 if (!pMsg)
2897 {
2898 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302899 return;
2900 }
2901
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302902 if (pData->bss_found)
2903 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2904 else
2905 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2906
Dino Mycle6fb96c12014-06-10 11:52:40 +05302907 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302908#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2909 NULL,
2910#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302911 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302912 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302913
2914 if (!skb) {
2915 hddLog(VOS_TRACE_LEVEL_ERROR,
2916 FL("cfg80211_vendor_event_alloc failed"));
2917 return;
2918 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302919
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302920 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2921 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2922 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2923 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2924
2925 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302926 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2927 "Ssid (%s) "
2928 "Bssid (" MAC_ADDRESS_STR ") "
2929 "Channel (%u) "
2930 "Rssi (%d) "
2931 "RTT (%u) "
2932 "RTT_SD (%u) ",
2933 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302934 pData->bssHotlist[i].ts,
2935 pData->bssHotlist[i].ssid,
2936 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2937 pData->bssHotlist[i].channel,
2938 pData->bssHotlist[i].rssi,
2939 pData->bssHotlist[i].rtt,
2940 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302941 }
2942
2943 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2944 pData->requestId) ||
2945 nla_put_u32(skb,
2946 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302947 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302948 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2949 goto fail;
2950 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302951 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302952 struct nlattr *aps;
2953
2954 aps = nla_nest_start(skb,
2955 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2956 if (!aps)
2957 goto fail;
2958
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302959 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302960 struct nlattr *ap;
2961
2962 ap = nla_nest_start(skb, i + 1);
2963 if (!ap)
2964 goto fail;
2965
2966 if (nla_put_u64(skb,
2967 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302968 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302969 nla_put(skb,
2970 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302971 sizeof(pData->bssHotlist[i].ssid),
2972 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302973 nla_put(skb,
2974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302975 sizeof(pData->bssHotlist[i].bssid),
2976 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302977 nla_put_u32(skb,
2978 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302979 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302980 nla_put_s32(skb,
2981 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302982 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302983 nla_put_u32(skb,
2984 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302985 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302986 nla_put_u32(skb,
2987 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302988 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302989 goto fail;
2990
2991 nla_nest_end(skb, ap);
2992 }
2993 nla_nest_end(skb, aps);
2994
2995 if (nla_put_u8(skb,
2996 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2997 pData->moreData))
2998 goto fail;
2999 }
3000
3001 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303002 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303003 return;
3004
3005fail:
3006 kfree_skb(skb);
3007 return;
3008
3009}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303010
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303011/**
3012 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
3013 * Handle an SSID hotlist match event
3014 * @ctx: HDD context registered with SME
3015 * @event: The SSID hotlist match event
3016 *
3017 * This function will take an SSID match event that was generated by
3018 * firmware and will convert it into a cfg80211 vendor event which is
3019 * sent to userspace.
3020 *
3021 * Return: none
3022 */
3023static void
3024wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
3025 void *pMsg)
3026{
3027 hdd_context_t *hdd_ctx = ctx;
3028 struct sk_buff *skb;
3029 tANI_U32 i, index;
3030 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3031
3032 ENTER();
3033
3034 if (wlan_hdd_validate_context(hdd_ctx)) {
3035 hddLog(LOGE,
3036 FL("HDD context is not valid or response"));
3037 return;
3038 }
3039 if (!pMsg)
3040 {
3041 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3042 return;
3043 }
3044
3045 if (pData->ssid_found) {
3046 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3047 hddLog(LOG1, "SSID hotlist found");
3048 } else {
3049 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3050 hddLog(LOG1, "SSID hotlist lost");
3051 }
3052
3053 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3054#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3055 NULL,
3056#endif
3057 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3058 index, GFP_KERNEL);
3059
3060 if (!skb) {
3061 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3062 return;
3063 }
3064 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3065 pData->requestId, pData->numHotlistSsid, pData->moreData);
3066
3067 for (i = 0; i < pData->numHotlistSsid; i++) {
3068 hddLog(LOG1, "[i=%d] Timestamp %llu "
3069 "Ssid: %s "
3070 "Bssid (" MAC_ADDRESS_STR ") "
3071 "Channel %u "
3072 "Rssi %d "
3073 "RTT %u "
3074 "RTT_SD %u",
3075 i,
3076 pData->ssidHotlist[i].ts,
3077 pData->ssidHotlist[i].ssid,
3078 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3079 pData->ssidHotlist[i].channel,
3080 pData->ssidHotlist[i].rssi,
3081 pData->ssidHotlist[i].rtt,
3082 pData->ssidHotlist[i].rtt_sd);
3083 }
3084
3085 if (nla_put_u32(skb,
3086 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3087 pData->requestId) ||
3088 nla_put_u32(skb,
3089 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3090 pData->numHotlistSsid)) {
3091 hddLog(LOGE, FL("put fail"));
3092 goto fail;
3093 }
3094
3095 if (pData->numHotlistSsid) {
3096 struct nlattr *aps;
3097 aps = nla_nest_start(skb,
3098 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3099 if (!aps) {
3100 hddLog(LOGE, FL("nest fail"));
3101 goto fail;
3102 }
3103
3104 for (i = 0; i < pData->numHotlistSsid; i++) {
3105 struct nlattr *ap;
3106
3107 ap = nla_nest_start(skb, i);
3108 if (!ap) {
3109 hddLog(LOGE, FL("nest fail"));
3110 goto fail;
3111 }
3112
3113 if (nla_put_u64(skb,
3114 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3115 pData->ssidHotlist[i].ts) ||
3116 nla_put(skb,
3117 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3118 sizeof(pData->ssidHotlist[i].ssid),
3119 pData->ssidHotlist[i].ssid) ||
3120 nla_put(skb,
3121 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3122 sizeof(pData->ssidHotlist[i].bssid),
3123 pData->ssidHotlist[i].bssid) ||
3124 nla_put_u32(skb,
3125 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3126 pData->ssidHotlist[i].channel) ||
3127 nla_put_s32(skb,
3128 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3129 pData->ssidHotlist[i].rssi) ||
3130 nla_put_u32(skb,
3131 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3132 pData->ssidHotlist[i].rtt) ||
3133 nla_put_u32(skb,
3134 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3135 pData->ssidHotlist[i].rtt_sd)) {
3136 hddLog(LOGE, FL("put fail"));
3137 goto fail;
3138 }
3139 nla_nest_end(skb, ap);
3140 }
3141 nla_nest_end(skb, aps);
3142
3143 if (nla_put_u8(skb,
3144 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3145 pData->moreData)) {
3146 hddLog(LOGE, FL("put fail"));
3147 goto fail;
3148 }
3149 }
3150
3151 cfg80211_vendor_event(skb, GFP_KERNEL);
3152 return;
3153
3154fail:
3155 kfree_skb(skb);
3156 return;
3157
3158}
3159
3160
Dino Mycle6fb96c12014-06-10 11:52:40 +05303161static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3162 void *pMsg)
3163{
3164 struct sk_buff *skb;
3165 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3166 tpSirWifiFullScanResultEvent pData =
3167 (tpSirWifiFullScanResultEvent) (pMsg);
3168
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303169 ENTER();
3170
3171 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303172 hddLog(LOGE,
3173 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303174 return;
3175 }
3176 if (!pMsg)
3177 {
3178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303179 return;
3180 }
3181
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303182 /*
3183 * If the full scan result including IE data exceeds NL 4K size
3184 * limitation, drop that beacon/probe rsp frame.
3185 */
3186 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3187 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3188 return;
3189 }
3190
Dino Mycle6fb96c12014-06-10 11:52:40 +05303191 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303192#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3193 NULL,
3194#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303195 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3196 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3197 GFP_KERNEL);
3198
3199 if (!skb) {
3200 hddLog(VOS_TRACE_LEVEL_ERROR,
3201 FL("cfg80211_vendor_event_alloc failed"));
3202 return;
3203 }
3204
Dino Mycle6fb96c12014-06-10 11:52:40 +05303205 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3206 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3207 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3208 "Ssid (%s)"
3209 "Bssid (" MAC_ADDRESS_STR ")"
3210 "Channel (%u)"
3211 "Rssi (%d)"
3212 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303213 "RTT_SD (%u)"
3214 "Bcn Period %d"
3215 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303216 pData->ap.ts,
3217 pData->ap.ssid,
3218 MAC_ADDR_ARRAY(pData->ap.bssid),
3219 pData->ap.channel,
3220 pData->ap.rssi,
3221 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303222 pData->ap.rtt_sd,
3223 pData->ap.beaconPeriod,
3224 pData->ap.capability);
3225
Dino Mycle6fb96c12014-06-10 11:52:40 +05303226 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3227 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3228 pData->requestId) ||
3229 nla_put_u64(skb,
3230 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3231 pData->ap.ts) ||
3232 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3233 sizeof(pData->ap.ssid),
3234 pData->ap.ssid) ||
3235 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3236 WNI_CFG_BSSID_LEN,
3237 pData->ap.bssid) ||
3238 nla_put_u32(skb,
3239 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3240 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303241 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303242 pData->ap.rssi) ||
3243 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3244 pData->ap.rtt) ||
3245 nla_put_u32(skb,
3246 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3247 pData->ap.rtt_sd) ||
3248 nla_put_u16(skb,
3249 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3250 pData->ap.beaconPeriod) ||
3251 nla_put_u16(skb,
3252 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3253 pData->ap.capability) ||
3254 nla_put_u32(skb,
3255 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303256 pData->ieLength) ||
3257 nla_put_u8(skb,
3258 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3259 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303260 {
3261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3262 goto nla_put_failure;
3263 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303264
3265 if (pData->ieLength) {
3266 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3267 pData->ieLength,
3268 pData->ie))
3269 {
3270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3271 goto nla_put_failure;
3272 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303273 }
3274
3275 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303276 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303277 return;
3278
3279nla_put_failure:
3280 kfree_skb(skb);
3281 return;
3282}
3283
3284static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3285 void *pMsg)
3286{
3287 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3288 struct sk_buff *skb = NULL;
3289 tpSirEXTScanResultsAvailableIndParams pData =
3290 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3291
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303292 ENTER();
3293
3294 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303295 hddLog(LOGE,
3296 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303297 return;
3298 }
3299 if (!pMsg)
3300 {
3301 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303302 return;
3303 }
3304
3305 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303306#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3307 NULL,
3308#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303309 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3310 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3311 GFP_KERNEL);
3312
3313 if (!skb) {
3314 hddLog(VOS_TRACE_LEVEL_ERROR,
3315 FL("cfg80211_vendor_event_alloc failed"));
3316 return;
3317 }
3318
Dino Mycle6fb96c12014-06-10 11:52:40 +05303319 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3320 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3321 pData->numResultsAvailable);
3322 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3323 pData->requestId) ||
3324 nla_put_u32(skb,
3325 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3326 pData->numResultsAvailable)) {
3327 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3328 goto nla_put_failure;
3329 }
3330
3331 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303332 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303333 return;
3334
3335nla_put_failure:
3336 kfree_skb(skb);
3337 return;
3338}
3339
3340static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3341{
3342 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3343 struct sk_buff *skb = NULL;
3344 tpSirEXTScanProgressIndParams pData =
3345 (tpSirEXTScanProgressIndParams) pMsg;
3346
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303347 ENTER();
3348
3349 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303350 hddLog(LOGE,
3351 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303352 return;
3353 }
3354 if (!pMsg)
3355 {
3356 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303357 return;
3358 }
3359
3360 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303361#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3362 NULL,
3363#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303364 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3365 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3366 GFP_KERNEL);
3367
3368 if (!skb) {
3369 hddLog(VOS_TRACE_LEVEL_ERROR,
3370 FL("cfg80211_vendor_event_alloc failed"));
3371 return;
3372 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303373 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303374 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3375 pData->extScanEventType);
3376 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3377 pData->status);
3378
3379 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3380 pData->extScanEventType) ||
3381 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303382 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3383 pData->requestId) ||
3384 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303385 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3386 pData->status)) {
3387 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3388 goto nla_put_failure;
3389 }
3390
3391 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303392 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303393 return;
3394
3395nla_put_failure:
3396 kfree_skb(skb);
3397 return;
3398}
3399
3400void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3401 void *pMsg)
3402{
3403 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3404
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303405 ENTER();
3406
Dino Mycle6fb96c12014-06-10 11:52:40 +05303407 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303408 return;
3409 }
3410
3411 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3412
3413
3414 switch(evType) {
3415 case SIR_HAL_EXTSCAN_START_RSP:
3416 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3417 break;
3418
3419 case SIR_HAL_EXTSCAN_STOP_RSP:
3420 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3421 break;
3422 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3423 /* There is no need to send this response to upper layer
3424 Just log the message */
3425 hddLog(VOS_TRACE_LEVEL_INFO,
3426 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3427 break;
3428 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3429 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3430 break;
3431
3432 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3433 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3434 break;
3435
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303436 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3437 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3438 break;
3439
3440 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3441 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3442 break;
3443
Dino Mycle6fb96c12014-06-10 11:52:40 +05303444 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303445 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303446 break;
3447 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3448 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3449 break;
3450 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3451 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3452 break;
3453 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3454 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3455 break;
3456 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3457 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3458 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303459 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3460 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3461 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303462 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3463 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3464 break;
3465 default:
3466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3467 break;
3468 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303469 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303470}
3471
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303472static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3473 struct wireless_dev *wdev,
3474 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303475{
Dino Myclee8843b32014-07-04 14:21:45 +05303476 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303477 struct net_device *dev = wdev->netdev;
3478 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3479 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3480 struct nlattr
3481 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3482 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303483 struct hdd_ext_scan_context *context;
3484 unsigned long rc;
3485 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303486
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303487 ENTER();
3488
Dino Mycle6fb96c12014-06-10 11:52:40 +05303489 status = wlan_hdd_validate_context(pHddCtx);
3490 if (0 != status)
3491 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303492 return -EINVAL;
3493 }
Dino Myclee8843b32014-07-04 14:21:45 +05303494 /* check the EXTScan Capability */
3495 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303496 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3497 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303498 {
3499 hddLog(VOS_TRACE_LEVEL_ERROR,
3500 FL("EXTScan not enabled/supported by Firmware"));
3501 return -EINVAL;
3502 }
3503
Dino Mycle6fb96c12014-06-10 11:52:40 +05303504 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3505 data, dataLen,
3506 wlan_hdd_extscan_config_policy)) {
3507 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3508 return -EINVAL;
3509 }
3510
3511 /* Parse and fetch request Id */
3512 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3513 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3514 return -EINVAL;
3515 }
3516
Dino Myclee8843b32014-07-04 14:21:45 +05303517 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303518 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303519 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303520
Dino Myclee8843b32014-07-04 14:21:45 +05303521 reqMsg.sessionId = pAdapter->sessionId;
3522 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303523
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303524 vos_spin_lock_acquire(&hdd_context_lock);
3525 context = &pHddCtx->ext_scan_context;
3526 context->request_id = reqMsg.requestId;
3527 INIT_COMPLETION(context->response_event);
3528 vos_spin_lock_release(&hdd_context_lock);
3529
Dino Myclee8843b32014-07-04 14:21:45 +05303530 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303531 if (!HAL_STATUS_SUCCESS(status)) {
3532 hddLog(VOS_TRACE_LEVEL_ERROR,
3533 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303534 return -EINVAL;
3535 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303536
3537 rc = wait_for_completion_timeout(&context->response_event,
3538 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3539 if (!rc) {
3540 hddLog(LOGE, FL("Target response timed out"));
3541 return -ETIMEDOUT;
3542 }
3543
3544 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3545 if (ret)
3546 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3547
3548 return ret;
3549
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303550 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303551 return 0;
3552}
3553
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303554static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3555 struct wireless_dev *wdev,
3556 const void *data, int dataLen)
3557{
3558 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303559
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303560 vos_ssr_protect(__func__);
3561 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3562 vos_ssr_unprotect(__func__);
3563
3564 return ret;
3565}
3566
3567static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3568 struct wireless_dev *wdev,
3569 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303570{
Dino Myclee8843b32014-07-04 14:21:45 +05303571 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303572 struct net_device *dev = wdev->netdev;
3573 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3574 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3575 struct nlattr
3576 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3577 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303578 struct hdd_ext_scan_context *context;
3579 unsigned long rc;
3580 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303581
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303582 ENTER();
3583
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303584 if (VOS_FTM_MODE == hdd_get_conparam()) {
3585 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3586 return -EINVAL;
3587 }
3588
Dino Mycle6fb96c12014-06-10 11:52:40 +05303589 status = wlan_hdd_validate_context(pHddCtx);
3590 if (0 != status)
3591 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303592 return -EINVAL;
3593 }
Dino Myclee8843b32014-07-04 14:21:45 +05303594 /* check the EXTScan Capability */
3595 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303596 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3597 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303598 {
3599 hddLog(VOS_TRACE_LEVEL_ERROR,
3600 FL("EXTScan not enabled/supported by Firmware"));
3601 return -EINVAL;
3602 }
3603
Dino Mycle6fb96c12014-06-10 11:52:40 +05303604 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3605 data, dataLen,
3606 wlan_hdd_extscan_config_policy)) {
3607 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3608 return -EINVAL;
3609 }
3610 /* Parse and fetch request Id */
3611 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3612 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3613 return -EINVAL;
3614 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303615
Dino Myclee8843b32014-07-04 14:21:45 +05303616 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303617 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3618
Dino Myclee8843b32014-07-04 14:21:45 +05303619 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303620
Dino Myclee8843b32014-07-04 14:21:45 +05303621 reqMsg.sessionId = pAdapter->sessionId;
3622 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303623
3624 /* Parse and fetch flush parameter */
3625 if (!tb
3626 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3627 {
3628 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3629 goto failed;
3630 }
Dino Myclee8843b32014-07-04 14:21:45 +05303631 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303632 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3633
Dino Myclee8843b32014-07-04 14:21:45 +05303634 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303635
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303636 spin_lock(&hdd_context_lock);
3637 context = &pHddCtx->ext_scan_context;
3638 context->request_id = reqMsg.requestId;
3639 context->ignore_cached_results = false;
3640 INIT_COMPLETION(context->response_event);
3641 spin_unlock(&hdd_context_lock);
3642
Dino Myclee8843b32014-07-04 14:21:45 +05303643 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303644 if (!HAL_STATUS_SUCCESS(status)) {
3645 hddLog(VOS_TRACE_LEVEL_ERROR,
3646 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303647 return -EINVAL;
3648 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303649
3650 rc = wait_for_completion_timeout(&context->response_event,
3651 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3652 if (!rc) {
3653 hddLog(LOGE, FL("Target response timed out"));
3654 retval = -ETIMEDOUT;
3655 spin_lock(&hdd_context_lock);
3656 context->ignore_cached_results = true;
3657 spin_unlock(&hdd_context_lock);
3658 } else {
3659 spin_lock(&hdd_context_lock);
3660 retval = context->response_status;
3661 spin_unlock(&hdd_context_lock);
3662 }
3663
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303664 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303665 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303666
3667failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303668 return -EINVAL;
3669}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303670static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3671 struct wireless_dev *wdev,
3672 const void *data, int dataLen)
3673{
3674 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303675
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303676 vos_ssr_protect(__func__);
3677 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3678 vos_ssr_unprotect(__func__);
3679
3680 return ret;
3681}
3682
3683static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303684 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303685 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303686{
3687 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3688 struct net_device *dev = wdev->netdev;
3689 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3690 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3691 struct nlattr
3692 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3693 struct nlattr
3694 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3695 struct nlattr *apTh;
3696 eHalStatus status;
3697 tANI_U8 i = 0;
3698 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303699 struct hdd_ext_scan_context *context;
3700 tANI_U32 request_id;
3701 unsigned long rc;
3702 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303703
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303704 ENTER();
3705
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303706 if (VOS_FTM_MODE == hdd_get_conparam()) {
3707 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3708 return -EINVAL;
3709 }
3710
Dino Mycle6fb96c12014-06-10 11:52:40 +05303711 status = wlan_hdd_validate_context(pHddCtx);
3712 if (0 != status)
3713 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303714 return -EINVAL;
3715 }
Dino Myclee8843b32014-07-04 14:21:45 +05303716 /* check the EXTScan Capability */
3717 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303718 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3719 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303720 {
3721 hddLog(VOS_TRACE_LEVEL_ERROR,
3722 FL("EXTScan not enabled/supported by Firmware"));
3723 return -EINVAL;
3724 }
3725
Dino Mycle6fb96c12014-06-10 11:52:40 +05303726 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3727 data, dataLen,
3728 wlan_hdd_extscan_config_policy)) {
3729 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3730 return -EINVAL;
3731 }
3732
3733 /* Parse and fetch request Id */
3734 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3735 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3736 return -EINVAL;
3737 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303738 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3739 vos_mem_malloc(sizeof(*pReqMsg));
3740 if (!pReqMsg) {
3741 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3742 return -ENOMEM;
3743 }
3744
Dino Myclee8843b32014-07-04 14:21:45 +05303745
Dino Mycle6fb96c12014-06-10 11:52:40 +05303746 pReqMsg->requestId = nla_get_u32(
3747 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3748 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3749
3750 /* Parse and fetch number of APs */
3751 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3752 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3753 goto fail;
3754 }
3755
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303756 /* Parse and fetch lost ap sample size */
3757 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3758 hddLog(LOGE, FL("attr lost ap sample size failed"));
3759 goto fail;
3760 }
3761
3762 pReqMsg->lostBssidSampleSize = nla_get_u32(
3763 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3764 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3765
Dino Mycle6fb96c12014-06-10 11:52:40 +05303766 pReqMsg->sessionId = pAdapter->sessionId;
3767 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3768
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303769 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303770 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303771 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303772
3773 nla_for_each_nested(apTh,
3774 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3775 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3776 nla_data(apTh), nla_len(apTh),
3777 NULL)) {
3778 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3779 goto fail;
3780 }
3781
3782 /* Parse and fetch MAC address */
3783 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3785 goto fail;
3786 }
3787 memcpy(pReqMsg->ap[i].bssid, nla_data(
3788 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3789 sizeof(tSirMacAddr));
3790 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3791
3792 /* Parse and fetch low RSSI */
3793 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3795 goto fail;
3796 }
3797 pReqMsg->ap[i].low = nla_get_s32(
3798 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3799 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3800
3801 /* Parse and fetch high RSSI */
3802 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3803 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3804 goto fail;
3805 }
3806 pReqMsg->ap[i].high = nla_get_s32(
3807 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3808 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3809 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303810 i++;
3811 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303812
3813 context = &pHddCtx->ext_scan_context;
3814 spin_lock(&hdd_context_lock);
3815 INIT_COMPLETION(context->response_event);
3816 context->request_id = request_id = pReqMsg->requestId;
3817 spin_unlock(&hdd_context_lock);
3818
Dino Mycle6fb96c12014-06-10 11:52:40 +05303819 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3820 if (!HAL_STATUS_SUCCESS(status)) {
3821 hddLog(VOS_TRACE_LEVEL_ERROR,
3822 FL("sme_SetBssHotlist failed(err=%d)"), status);
3823 vos_mem_free(pReqMsg);
3824 return -EINVAL;
3825 }
3826
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303827 /* request was sent -- wait for the response */
3828 rc = wait_for_completion_timeout(&context->response_event,
3829 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3830
3831 if (!rc) {
3832 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3833 retval = -ETIMEDOUT;
3834 } else {
3835 spin_lock(&hdd_context_lock);
3836 if (context->request_id == request_id)
3837 retval = context->response_status;
3838 else
3839 retval = -EINVAL;
3840 spin_unlock(&hdd_context_lock);
3841 }
3842
Dino Myclee8843b32014-07-04 14:21:45 +05303843 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303844 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303845 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303846
3847fail:
3848 vos_mem_free(pReqMsg);
3849 return -EINVAL;
3850}
3851
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303852static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3853 struct wireless_dev *wdev,
3854 const void *data, int dataLen)
3855{
3856 int ret = 0;
3857
3858 vos_ssr_protect(__func__);
3859 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3860 dataLen);
3861 vos_ssr_unprotect(__func__);
3862
3863 return ret;
3864}
3865
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303866/*
3867 * define short names for the global vendor params
3868 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3869 */
3870#define PARAM_MAX \
3871QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3872#define PARAM_REQUEST_ID \
3873QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3874#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3875QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3876#define PARAMS_NUM_SSID \
3877QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3878#define THRESHOLD_PARAM \
3879QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3880#define PARAM_SSID \
3881QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3882#define PARAM_BAND \
3883QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3884#define PARAM_RSSI_LOW \
3885QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3886#define PARAM_RSSI_HIGH \
3887QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3888
3889/**
3890 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3891 * @wiphy: Pointer to wireless phy
3892 * @wdev: Pointer to wireless device
3893 * @data: Pointer to data
3894 * @data_len: Data length
3895 *
3896 * Return: 0 on success, negative errno on failure
3897 */
3898static int
3899__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3900 struct wireless_dev *wdev,
3901 const void *data,
3902 int data_len)
3903{
3904 tSirEXTScanSetSsidHotListReqParams *request;
3905 struct net_device *dev = wdev->netdev;
3906 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3907 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3908 struct nlattr *tb[PARAM_MAX + 1];
3909 struct nlattr *tb2[PARAM_MAX + 1];
3910 struct nlattr *ssids;
3911 struct hdd_ext_scan_context *context;
3912 uint32_t request_id;
3913 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3914 int ssid_len;
Anurag Chouhand64d5232016-08-29 17:01:38 +05303915 int ssid_length;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303916 eHalStatus status;
3917 int i, rem, retval;
3918 unsigned long rc;
3919
3920 ENTER();
3921
3922 if (VOS_FTM_MODE == hdd_get_conparam()) {
3923 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3924 return -EINVAL;
3925 }
3926
3927 retval = wlan_hdd_validate_context(hdd_ctx);
3928 if (0 != retval) {
3929 hddLog(LOGE, FL("HDD context is not valid"));
3930 return -EINVAL;
3931 }
3932
3933 /* check the EXTScan Capability */
3934 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303935 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3936 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303937 {
3938 hddLog(VOS_TRACE_LEVEL_ERROR,
3939 FL("EXTScan not enabled/supported by Firmware"));
3940 return -EINVAL;
3941 }
3942
3943 if (nla_parse(tb, PARAM_MAX,
3944 data, data_len,
3945 wlan_hdd_extscan_config_policy)) {
3946 hddLog(LOGE, FL("Invalid ATTR"));
3947 return -EINVAL;
3948 }
3949
3950 request = vos_mem_malloc(sizeof(*request));
3951 if (!request) {
3952 hddLog(LOGE, FL("vos_mem_malloc failed"));
3953 return -ENOMEM;
3954 }
3955
3956 /* Parse and fetch request Id */
3957 if (!tb[PARAM_REQUEST_ID]) {
3958 hddLog(LOGE, FL("attr request id failed"));
3959 goto fail;
3960 }
3961
3962 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3963 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3964
3965 /* Parse and fetch lost SSID sample size */
3966 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3967 hddLog(LOGE, FL("attr number of Ssid failed"));
3968 goto fail;
3969 }
3970 request->lost_ssid_sample_size =
3971 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3972 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3973 request->lost_ssid_sample_size);
3974
3975 /* Parse and fetch number of hotlist SSID */
3976 if (!tb[PARAMS_NUM_SSID]) {
3977 hddLog(LOGE, FL("attr number of Ssid failed"));
3978 goto fail;
3979 }
3980 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3981 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3982
3983 request->session_id = adapter->sessionId;
3984 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3985
3986 i = 0;
3987 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3988 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3989 hddLog(LOGE,
3990 FL("Too Many SSIDs, %d exceeds %d"),
3991 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3992 break;
3993 }
3994 if (nla_parse(tb2, PARAM_MAX,
3995 nla_data(ssids), nla_len(ssids),
3996 wlan_hdd_extscan_config_policy)) {
3997 hddLog(LOGE, FL("nla_parse failed"));
3998 goto fail;
3999 }
4000
4001 /* Parse and fetch SSID */
4002 if (!tb2[PARAM_SSID]) {
4003 hddLog(LOGE, FL("attr ssid failed"));
4004 goto fail;
4005 }
Anurag Chouhand64d5232016-08-29 17:01:38 +05304006 ssid_length = nla_strlcpy(ssid_string, tb2[PARAM_SSID],
4007 sizeof(ssid_string));
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304008 hddLog(LOG1, FL("SSID %s"),
4009 ssid_string);
4010 ssid_len = strlen(ssid_string);
SaidiReddy Yenugae4f6f372016-12-06 16:11:39 +05304011 if (ssid_length >= SIR_MAC_MAX_SSID_LENGTH) {
Anurag Chouhand64d5232016-08-29 17:01:38 +05304012 hddLog(LOGE, FL("Invalid ssid length"));
4013 goto fail;
4014 }
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304015 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
4016 request->ssid[i].ssid.length = ssid_len;
4017 request->ssid[i].ssid.ssId[ssid_len] = '\0';
4018 hddLog(LOG1, FL("After copying SSID %s"),
4019 request->ssid[i].ssid.ssId);
4020 hddLog(LOG1, FL("After copying length: %d"),
4021 ssid_len);
4022
4023 /* Parse and fetch low RSSI */
4024 if (!tb2[PARAM_BAND]) {
4025 hddLog(LOGE, FL("attr band failed"));
4026 goto fail;
4027 }
4028 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
4029 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
4030
4031 /* Parse and fetch low RSSI */
4032 if (!tb2[PARAM_RSSI_LOW]) {
4033 hddLog(LOGE, FL("attr low RSSI failed"));
4034 goto fail;
4035 }
4036 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
4037 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
4038
4039 /* Parse and fetch high RSSI */
4040 if (!tb2[PARAM_RSSI_HIGH]) {
4041 hddLog(LOGE, FL("attr high RSSI failed"));
4042 goto fail;
4043 }
4044 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4045 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4046 i++;
4047 }
4048
4049 context = &hdd_ctx->ext_scan_context;
4050 spin_lock(&hdd_context_lock);
4051 INIT_COMPLETION(context->response_event);
4052 context->request_id = request_id = request->request_id;
4053 spin_unlock(&hdd_context_lock);
4054
4055 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4056 if (!HAL_STATUS_SUCCESS(status)) {
4057 hddLog(LOGE,
4058 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4059 goto fail;
4060 }
4061
4062 vos_mem_free(request);
4063
4064 /* request was sent -- wait for the response */
4065 rc = wait_for_completion_timeout(&context->response_event,
4066 msecs_to_jiffies
4067 (WLAN_WAIT_TIME_EXTSCAN));
4068 if (!rc) {
4069 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4070 retval = -ETIMEDOUT;
4071 } else {
4072 spin_lock(&hdd_context_lock);
4073 if (context->request_id == request_id)
4074 retval = context->response_status;
4075 else
4076 retval = -EINVAL;
4077 spin_unlock(&hdd_context_lock);
4078 }
4079
4080 return retval;
4081
4082fail:
4083 vos_mem_free(request);
4084 return -EINVAL;
4085}
4086
4087/*
4088 * done with short names for the global vendor params
4089 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4090 */
4091#undef PARAM_MAX
4092#undef PARAM_REQUEST_ID
4093#undef PARAMS_NUM_SSID
4094#undef THRESHOLD_PARAM
4095#undef PARAM_SSID
4096#undef PARAM_BAND
4097#undef PARAM_RSSI_LOW
4098#undef PARAM_RSSI_HIGH
4099
4100static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4101 struct wireless_dev *wdev,
4102 const void *data, int dataLen)
4103{
4104 int ret = 0;
4105
4106 vos_ssr_protect(__func__);
4107 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4108 dataLen);
4109 vos_ssr_unprotect(__func__);
4110
4111 return ret;
4112}
4113
4114static int
4115__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4116 struct wireless_dev *wdev,
4117 const void *data,
4118 int data_len)
4119{
4120 tSirEXTScanResetSsidHotlistReqParams request;
4121 struct net_device *dev = wdev->netdev;
4122 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4123 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4124 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4125 struct hdd_ext_scan_context *context;
4126 uint32_t request_id;
4127 eHalStatus status;
4128 int retval;
4129 unsigned long rc;
4130
4131 ENTER();
4132
4133 if (VOS_FTM_MODE == hdd_get_conparam()) {
4134 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4135 return -EINVAL;
4136 }
4137
4138 retval = wlan_hdd_validate_context(hdd_ctx);
4139 if (0 != retval) {
4140 hddLog(LOGE, FL("HDD context is not valid"));
4141 return -EINVAL;
4142 }
4143
4144 /* check the EXTScan Capability */
4145 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304146 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4147 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304148 {
4149 hddLog(LOGE,
4150 FL("EXTScan not enabled/supported by Firmware"));
4151 return -EINVAL;
4152 }
4153
4154 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4155 data, data_len,
4156 wlan_hdd_extscan_config_policy)) {
4157 hddLog(LOGE, FL("Invalid ATTR"));
4158 return -EINVAL;
4159 }
4160
4161 /* Parse and fetch request Id */
4162 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4163 hddLog(LOGE, FL("attr request id failed"));
4164 return -EINVAL;
4165 }
4166
4167 request.requestId = nla_get_u32(
4168 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4169 request.sessionId = adapter->sessionId;
4170 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4171 request.sessionId);
4172
4173 context = &hdd_ctx->ext_scan_context;
4174 spin_lock(&hdd_context_lock);
4175 INIT_COMPLETION(context->response_event);
4176 context->request_id = request_id = request.requestId;
4177 spin_unlock(&hdd_context_lock);
4178
4179 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4180 if (!HAL_STATUS_SUCCESS(status)) {
4181 hddLog(LOGE,
4182 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4183 return -EINVAL;
4184 }
4185
4186 /* request was sent -- wait for the response */
4187 rc = wait_for_completion_timeout(&context->response_event,
4188 msecs_to_jiffies
4189 (WLAN_WAIT_TIME_EXTSCAN));
4190 if (!rc) {
4191 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4192 retval = -ETIMEDOUT;
4193 } else {
4194 spin_lock(&hdd_context_lock);
4195 if (context->request_id == request_id)
4196 retval = context->response_status;
4197 else
4198 retval = -EINVAL;
4199 spin_unlock(&hdd_context_lock);
4200 }
4201
4202 return retval;
4203}
4204
4205static int
4206wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4207 struct wireless_dev *wdev,
4208 const void *data,
4209 int data_len)
4210{
4211 int ret;
4212
4213 vos_ssr_protect(__func__);
4214 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4215 data, data_len);
4216 vos_ssr_unprotect(__func__);
4217
4218 return ret;
4219}
4220
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304221static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304222 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304223 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304224{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304225 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4226 struct net_device *dev = wdev->netdev;
4227 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4228 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4229 uint8_t num_channels = 0;
4230 uint8_t num_chan_new = 0;
4231 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304232 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304233 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304234 tWifiBand wifiBand;
4235 eHalStatus status;
4236 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304237 tANI_U8 i,j,k;
4238 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304239
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304240 ENTER();
4241
Dino Mycle6fb96c12014-06-10 11:52:40 +05304242 status = wlan_hdd_validate_context(pHddCtx);
4243 if (0 != status)
4244 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304245 return -EINVAL;
4246 }
Dino Myclee8843b32014-07-04 14:21:45 +05304247
Dino Mycle6fb96c12014-06-10 11:52:40 +05304248 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4249 data, dataLen,
4250 wlan_hdd_extscan_config_policy)) {
4251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4252 return -EINVAL;
4253 }
4254
4255 /* Parse and fetch request Id */
4256 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4257 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4258 return -EINVAL;
4259 }
4260 requestId = nla_get_u32(
4261 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4262 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4263
4264 /* Parse and fetch wifi band */
4265 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4266 {
4267 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4268 return -EINVAL;
4269 }
4270 wifiBand = nla_get_u32(
4271 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4272 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4273
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304274 /* Parse and fetch max channels */
4275 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4276 {
4277 hddLog(LOGE, FL("attr max channels failed"));
4278 return -EINVAL;
4279 }
4280 maxChannels = nla_get_u32(
4281 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4282 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4283
Dino Mycle6fb96c12014-06-10 11:52:40 +05304284 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304285 wifiBand, chan_list,
4286 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304287 if (eHAL_STATUS_SUCCESS != status) {
4288 hddLog(VOS_TRACE_LEVEL_ERROR,
4289 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4290 return -EINVAL;
4291 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304292
Agrawal Ashish16abf782016-08-18 22:42:59 +05304293 num_channels = VOS_MIN(num_channels, maxChannels);
4294 num_chan_new = num_channels;
4295 /* remove the indoor only channels if iface is SAP */
4296 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4297 {
4298 num_chan_new = 0;
4299 for (i = 0; i < num_channels; i++)
4300 for (j = 0; j < IEEE80211_NUM_BANDS; j++) {
4301 if (wiphy->bands[j] == NULL)
4302 continue;
4303 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4304 if ((chan_list[i] ==
4305 wiphy->bands[j]->channels[k].center_freq) &&
4306 (!(wiphy->bands[j]->channels[k].flags &
4307 IEEE80211_CHAN_INDOOR_ONLY))) {
4308 chan_list[num_chan_new] = chan_list[i];
4309 num_chan_new++;
4310 }
4311 }
4312 }
4313 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304314
Agrawal Ashish16abf782016-08-18 22:42:59 +05304315 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4316 for (i = 0; i < num_chan_new; i++)
4317 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4318 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304319
4320 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304321 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304322 NLMSG_HDRLEN);
4323
4324 if (!replySkb) {
4325 hddLog(VOS_TRACE_LEVEL_ERROR,
4326 FL("valid channels: buffer alloc fail"));
4327 return -EINVAL;
4328 }
4329 if (nla_put_u32(replySkb,
4330 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304331 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304332 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304333 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304334
4335 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4336 kfree_skb(replySkb);
4337 return -EINVAL;
4338 }
4339
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304340 ret = cfg80211_vendor_cmd_reply(replySkb);
4341
4342 EXIT();
4343 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304344}
4345
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304346static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4347 struct wireless_dev *wdev,
4348 const void *data, int dataLen)
4349{
4350 int ret = 0;
4351
4352 vos_ssr_protect(__func__);
4353 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4354 dataLen);
4355 vos_ssr_unprotect(__func__);
4356
4357 return ret;
4358}
4359
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304360static int hdd_extscan_start_fill_bucket_channel_spec(
4361 hdd_context_t *pHddCtx,
4362 tpSirEXTScanStartReqParams pReqMsg,
4363 struct nlattr **tb)
4364{
4365 struct nlattr *bucket[
4366 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4367 struct nlattr *channel[
4368 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4369 struct nlattr *buckets;
4370 struct nlattr *channels;
4371 int rem1, rem2;
4372 eHalStatus status;
4373 tANI_U8 bktIndex, j, numChannels;
4374 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4375 tANI_U32 passive_max_chn_time, active_max_chn_time;
4376
4377 bktIndex = 0;
4378
4379 nla_for_each_nested(buckets,
4380 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4381 if (nla_parse(bucket,
4382 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4383 nla_data(buckets), nla_len(buckets), NULL)) {
4384 hddLog(LOGE, FL("nla_parse failed"));
4385 return -EINVAL;
4386 }
4387
4388 /* Parse and fetch bucket spec */
4389 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4390 hddLog(LOGE, FL("attr bucket index failed"));
4391 return -EINVAL;
4392 }
4393 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4394 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4395 hddLog(LOG1, FL("Bucket spec Index %d"),
4396 pReqMsg->buckets[bktIndex].bucket);
4397
4398 /* Parse and fetch wifi band */
4399 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4400 hddLog(LOGE, FL("attr wifi band failed"));
4401 return -EINVAL;
4402 }
4403 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4404 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4405 hddLog(LOG1, FL("Wifi band %d"),
4406 pReqMsg->buckets[bktIndex].band);
4407
4408 /* Parse and fetch period */
4409 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4410 hddLog(LOGE, FL("attr period failed"));
4411 return -EINVAL;
4412 }
4413 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4414 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4415 hddLog(LOG1, FL("period %d"),
4416 pReqMsg->buckets[bktIndex].period);
4417
4418 /* Parse and fetch report events */
4419 if (!bucket[
4420 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4421 hddLog(LOGE, FL("attr report events failed"));
4422 return -EINVAL;
4423 }
4424 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4425 bucket[
4426 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4427 hddLog(LOG1, FL("report events %d"),
4428 pReqMsg->buckets[bktIndex].reportEvents);
4429
4430 /* Parse and fetch max period */
4431 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4432 hddLog(LOGE, FL("attr max period failed"));
4433 return -EINVAL;
4434 }
4435 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4436 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4437 hddLog(LOG1, FL("max period %u"),
4438 pReqMsg->buckets[bktIndex].max_period);
4439
4440 /* Parse and fetch exponent */
4441 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4442 hddLog(LOGE, FL("attr exponent failed"));
4443 return -EINVAL;
4444 }
4445 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4446 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4447 hddLog(LOG1, FL("exponent %u"),
4448 pReqMsg->buckets[bktIndex].exponent);
4449
4450 /* Parse and fetch step count */
4451 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4452 hddLog(LOGE, FL("attr step count failed"));
4453 return -EINVAL;
4454 }
4455 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4456 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4457 hddLog(LOG1, FL("Step count %u"),
4458 pReqMsg->buckets[bktIndex].step_count);
4459
4460 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4461 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4462
4463 /* Framework shall pass the channel list if the input WiFi band is
4464 * WIFI_BAND_UNSPECIFIED.
4465 * If the input WiFi band is specified (any value other than
4466 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4467 */
4468 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4469 numChannels = 0;
4470 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4471 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4472 pReqMsg->buckets[bktIndex].band,
4473 chanList, &numChannels);
4474 if (!HAL_STATUS_SUCCESS(status)) {
4475 hddLog(LOGE,
4476 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4477 status);
4478 return -EINVAL;
4479 }
4480
4481 pReqMsg->buckets[bktIndex].numChannels =
4482 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4483 hddLog(LOG1, FL("Num channels %d"),
4484 pReqMsg->buckets[bktIndex].numChannels);
4485
4486 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4487 j++) {
4488 pReqMsg->buckets[bktIndex].channels[j].channel =
4489 chanList[j];
4490 pReqMsg->buckets[bktIndex].channels[j].
4491 chnlClass = 0;
4492 if (CSR_IS_CHANNEL_DFS(
4493 vos_freq_to_chan(chanList[j]))) {
4494 pReqMsg->buckets[bktIndex].channels[j].
4495 passive = 1;
4496 pReqMsg->buckets[bktIndex].channels[j].
4497 dwellTimeMs = passive_max_chn_time;
4498 } else {
4499 pReqMsg->buckets[bktIndex].channels[j].
4500 passive = 0;
4501 pReqMsg->buckets[bktIndex].channels[j].
4502 dwellTimeMs = active_max_chn_time;
4503 }
4504
4505 hddLog(LOG1,
4506 "Channel %u Passive %u Dwell time %u ms",
4507 pReqMsg->buckets[bktIndex].channels[j].channel,
4508 pReqMsg->buckets[bktIndex].channels[j].passive,
4509 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4510 }
4511
4512 bktIndex++;
4513 continue;
4514 }
4515
4516 /* Parse and fetch number of channels */
4517 if (!bucket[
4518 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4519 hddLog(LOGE, FL("attr num channels failed"));
4520 return -EINVAL;
4521 }
4522
4523 pReqMsg->buckets[bktIndex].numChannels =
4524 nla_get_u32(bucket[
4525 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4526 hddLog(LOG1, FL("num channels %d"),
4527 pReqMsg->buckets[bktIndex].numChannels);
4528
4529 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4530 hddLog(LOGE, FL("attr channel spec failed"));
4531 return -EINVAL;
4532 }
4533
4534 j = 0;
4535 nla_for_each_nested(channels,
4536 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4537 if (nla_parse(channel,
4538 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4539 nla_data(channels), nla_len(channels),
4540 wlan_hdd_extscan_config_policy)) {
4541 hddLog(LOGE, FL("nla_parse failed"));
4542 return -EINVAL;
4543 }
4544
4545 /* Parse and fetch channel */
4546 if (!channel[
4547 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4548 hddLog(LOGE, FL("attr channel failed"));
4549 return -EINVAL;
4550 }
4551 pReqMsg->buckets[bktIndex].channels[j].channel =
4552 nla_get_u32(channel[
4553 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4554 hddLog(LOG1, FL("channel %u"),
4555 pReqMsg->buckets[bktIndex].channels[j].channel);
4556
4557 /* Parse and fetch dwell time */
4558 if (!channel[
4559 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4560 hddLog(LOGE, FL("attr dwelltime failed"));
4561 return -EINVAL;
4562 }
4563 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4564 nla_get_u32(channel[
4565 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4566
4567 hddLog(LOG1, FL("Dwell time (%u ms)"),
4568 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4569
4570
4571 /* Parse and fetch channel spec passive */
4572 if (!channel[
4573 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4574 hddLog(LOGE,
4575 FL("attr channel spec passive failed"));
4576 return -EINVAL;
4577 }
4578 pReqMsg->buckets[bktIndex].channels[j].passive =
4579 nla_get_u8(channel[
4580 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4581 hddLog(LOG1, FL("Chnl spec passive %u"),
4582 pReqMsg->buckets[bktIndex].channels[j].passive);
4583
4584 j++;
4585 }
4586
4587 bktIndex++;
4588 }
4589
4590 return 0;
4591}
4592
4593
4594/*
4595 * define short names for the global vendor params
4596 * used by wlan_hdd_cfg80211_extscan_start()
4597 */
4598#define PARAM_MAX \
4599QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4600#define PARAM_REQUEST_ID \
4601QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4602#define PARAM_BASE_PERIOD \
4603QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4604#define PARAM_MAX_AP_PER_SCAN \
4605QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4606#define PARAM_RPT_THRHLD_PERCENT \
4607QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4608#define PARAM_RPT_THRHLD_NUM_SCANS \
4609QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4610#define PARAM_NUM_BUCKETS \
4611QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4612
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304613static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304614 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304615 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304616{
Dino Myclee8843b32014-07-04 14:21:45 +05304617 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304618 struct net_device *dev = wdev->netdev;
4619 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4620 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4621 struct nlattr *tb[PARAM_MAX + 1];
4622 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304623 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304624 tANI_U32 request_id;
4625 struct hdd_ext_scan_context *context;
4626 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304627
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304628 ENTER();
4629
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304630 if (VOS_FTM_MODE == hdd_get_conparam()) {
4631 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4632 return -EINVAL;
4633 }
4634
Dino Mycle6fb96c12014-06-10 11:52:40 +05304635 status = wlan_hdd_validate_context(pHddCtx);
4636 if (0 != status)
4637 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304638 return -EINVAL;
4639 }
Dino Myclee8843b32014-07-04 14:21:45 +05304640 /* check the EXTScan Capability */
4641 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304642 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4643 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304644 {
4645 hddLog(VOS_TRACE_LEVEL_ERROR,
4646 FL("EXTScan not enabled/supported by Firmware"));
4647 return -EINVAL;
4648 }
4649
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304650 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304651 data, dataLen,
4652 wlan_hdd_extscan_config_policy)) {
4653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4654 return -EINVAL;
4655 }
4656
4657 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304658 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4660 return -EINVAL;
4661 }
4662
Dino Myclee8843b32014-07-04 14:21:45 +05304663 pReqMsg = (tpSirEXTScanStartReqParams)
4664 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304665 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304666 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4667 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304668 }
4669
4670 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304671 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304672 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4673
4674 pReqMsg->sessionId = pAdapter->sessionId;
4675 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4676
4677 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304678 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4680 goto fail;
4681 }
4682 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304683 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304684 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4685 pReqMsg->basePeriod);
4686
4687 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304688 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304689 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4690 goto fail;
4691 }
4692 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304693 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304694 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4695 pReqMsg->maxAPperScan);
4696
4697 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304698 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304699 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4700 goto fail;
4701 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304702 pReqMsg->reportThresholdPercent = nla_get_u8(
4703 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304704 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304705 pReqMsg->reportThresholdPercent);
4706
4707 /* Parse and fetch report threshold num scans */
4708 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4709 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4710 goto fail;
4711 }
4712 pReqMsg->reportThresholdNumScans = nla_get_u8(
4713 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4714 hddLog(LOG1, FL("Report Threshold num scans %d"),
4715 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304716
4717 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304718 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304719 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4720 goto fail;
4721 }
4722 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304723 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304724 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4725 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4726 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4727 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4728 }
4729 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4730 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304731
Dino Mycle6fb96c12014-06-10 11:52:40 +05304732 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4733 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4734 goto fail;
4735 }
4736
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304737 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304738
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304739 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4740 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304741
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304742 context = &pHddCtx->ext_scan_context;
4743 spin_lock(&hdd_context_lock);
4744 INIT_COMPLETION(context->response_event);
4745 context->request_id = request_id = pReqMsg->requestId;
4746 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304747
Dino Mycle6fb96c12014-06-10 11:52:40 +05304748 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4749 if (!HAL_STATUS_SUCCESS(status)) {
4750 hddLog(VOS_TRACE_LEVEL_ERROR,
4751 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304752 goto fail;
4753 }
4754
Srinivas Dasari91727c12016-03-23 17:59:06 +05304755 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
4756
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304757 /* request was sent -- wait for the response */
4758 rc = wait_for_completion_timeout(&context->response_event,
4759 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4760
4761 if (!rc) {
4762 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4763 retval = -ETIMEDOUT;
4764 } else {
4765 spin_lock(&hdd_context_lock);
4766 if (context->request_id == request_id)
4767 retval = context->response_status;
4768 else
4769 retval = -EINVAL;
4770 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304771 }
4772
Dino Myclee8843b32014-07-04 14:21:45 +05304773 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304774 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304775 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304776
4777fail:
4778 vos_mem_free(pReqMsg);
4779 return -EINVAL;
4780}
4781
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304782/*
4783 * done with short names for the global vendor params
4784 * used by wlan_hdd_cfg80211_extscan_start()
4785 */
4786#undef PARAM_MAX
4787#undef PARAM_REQUEST_ID
4788#undef PARAM_BASE_PERIOD
4789#undef PARAMS_MAX_AP_PER_SCAN
4790#undef PARAMS_RPT_THRHLD_PERCENT
4791#undef PARAMS_RPT_THRHLD_NUM_SCANS
4792#undef PARAMS_NUM_BUCKETS
4793
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304794static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4795 struct wireless_dev *wdev,
4796 const void *data, int dataLen)
4797{
4798 int ret = 0;
4799
4800 vos_ssr_protect(__func__);
4801 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4802 vos_ssr_unprotect(__func__);
4803
4804 return ret;
4805}
4806
4807static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304808 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304809 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304810{
Dino Myclee8843b32014-07-04 14:21:45 +05304811 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304812 struct net_device *dev = wdev->netdev;
4813 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4814 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4815 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4816 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304817 int retval;
4818 unsigned long rc;
4819 struct hdd_ext_scan_context *context;
4820 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304821
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304822 ENTER();
4823
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304824 if (VOS_FTM_MODE == hdd_get_conparam()) {
4825 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4826 return -EINVAL;
4827 }
4828
Dino Mycle6fb96c12014-06-10 11:52:40 +05304829 status = wlan_hdd_validate_context(pHddCtx);
4830 if (0 != status)
4831 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304832 return -EINVAL;
4833 }
Dino Myclee8843b32014-07-04 14:21:45 +05304834 /* check the EXTScan Capability */
4835 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304836 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4837 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304838 {
4839 hddLog(VOS_TRACE_LEVEL_ERROR,
4840 FL("EXTScan not enabled/supported by Firmware"));
4841 return -EINVAL;
4842 }
4843
Dino Mycle6fb96c12014-06-10 11:52:40 +05304844 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4845 data, dataLen,
4846 wlan_hdd_extscan_config_policy)) {
4847 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4848 return -EINVAL;
4849 }
4850
4851 /* Parse and fetch request Id */
4852 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4853 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4854 return -EINVAL;
4855 }
4856
Dino Myclee8843b32014-07-04 14:21:45 +05304857 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304858 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304859 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304860
Dino Myclee8843b32014-07-04 14:21:45 +05304861 reqMsg.sessionId = pAdapter->sessionId;
4862 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304863
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304864 context = &pHddCtx->ext_scan_context;
4865 spin_lock(&hdd_context_lock);
4866 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05304867 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304868 spin_unlock(&hdd_context_lock);
4869
Dino Myclee8843b32014-07-04 14:21:45 +05304870 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304871 if (!HAL_STATUS_SUCCESS(status)) {
4872 hddLog(VOS_TRACE_LEVEL_ERROR,
4873 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304874 return -EINVAL;
4875 }
4876
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304877 /* request was sent -- wait for the response */
4878 rc = wait_for_completion_timeout(&context->response_event,
4879 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4880
4881 if (!rc) {
4882 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4883 retval = -ETIMEDOUT;
4884 } else {
4885 spin_lock(&hdd_context_lock);
4886 if (context->request_id == request_id)
4887 retval = context->response_status;
4888 else
4889 retval = -EINVAL;
4890 spin_unlock(&hdd_context_lock);
4891 }
4892
4893 return retval;
4894
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304895 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304896 return 0;
4897}
4898
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304899static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4900 struct wireless_dev *wdev,
4901 const void *data, int dataLen)
4902{
4903 int ret = 0;
4904
4905 vos_ssr_protect(__func__);
4906 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4907 vos_ssr_unprotect(__func__);
4908
4909 return ret;
4910}
4911
4912static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304913 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304914 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304915{
Dino Myclee8843b32014-07-04 14:21:45 +05304916 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304917 struct net_device *dev = wdev->netdev;
4918 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4919 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4920 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4921 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304922 struct hdd_ext_scan_context *context;
4923 tANI_U32 request_id;
4924 unsigned long rc;
4925 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304926
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304927 ENTER();
4928
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304929 if (VOS_FTM_MODE == hdd_get_conparam()) {
4930 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4931 return -EINVAL;
4932 }
4933
Dino Mycle6fb96c12014-06-10 11:52:40 +05304934 status = wlan_hdd_validate_context(pHddCtx);
4935 if (0 != status)
4936 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304937 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304938 return -EINVAL;
4939 }
Dino Myclee8843b32014-07-04 14:21:45 +05304940 /* check the EXTScan Capability */
4941 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304942 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4943 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304944 {
4945 hddLog(VOS_TRACE_LEVEL_ERROR,
4946 FL("EXTScan not enabled/supported by Firmware"));
4947 return -EINVAL;
4948 }
4949
Dino Mycle6fb96c12014-06-10 11:52:40 +05304950 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4951 data, dataLen,
4952 wlan_hdd_extscan_config_policy)) {
4953 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4954 return -EINVAL;
4955 }
4956
4957 /* Parse and fetch request Id */
4958 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4959 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4960 return -EINVAL;
4961 }
4962
Dino Myclee8843b32014-07-04 14:21:45 +05304963 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304964 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304965 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304966
Dino Myclee8843b32014-07-04 14:21:45 +05304967 reqMsg.sessionId = pAdapter->sessionId;
4968 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304969
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304970 context = &pHddCtx->ext_scan_context;
4971 spin_lock(&hdd_context_lock);
4972 INIT_COMPLETION(context->response_event);
4973 context->request_id = request_id = reqMsg.requestId;
4974 spin_unlock(&hdd_context_lock);
4975
Dino Myclee8843b32014-07-04 14:21:45 +05304976 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304977 if (!HAL_STATUS_SUCCESS(status)) {
4978 hddLog(VOS_TRACE_LEVEL_ERROR,
4979 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304980 return -EINVAL;
4981 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304982
4983 /* request was sent -- wait for the response */
4984 rc = wait_for_completion_timeout(&context->response_event,
4985 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4986 if (!rc) {
4987 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4988 retval = -ETIMEDOUT;
4989 } else {
4990 spin_lock(&hdd_context_lock);
4991 if (context->request_id == request_id)
4992 retval = context->response_status;
4993 else
4994 retval = -EINVAL;
4995 spin_unlock(&hdd_context_lock);
4996 }
4997
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304998 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304999 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305000}
5001
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305002static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5003 struct wireless_dev *wdev,
5004 const void *data, int dataLen)
5005{
5006 int ret = 0;
5007
5008 vos_ssr_protect(__func__);
5009 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5010 vos_ssr_unprotect(__func__);
5011
5012 return ret;
5013}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305014#endif /* WLAN_FEATURE_EXTSCAN */
5015
Atul Mittal115287b2014-07-08 13:26:33 +05305016/*EXT TDLS*/
5017static const struct nla_policy
5018wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5019{
5020 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5021 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5022 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5023 {.type = NLA_S32 },
5024 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5025 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5026
5027};
5028
5029static const struct nla_policy
5030wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5031{
5032 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5033
5034};
5035
5036static const struct nla_policy
5037wlan_hdd_tdls_config_state_change_policy[
5038 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5039{
5040 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
5041 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5042 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305043 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5044 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5045 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305046
5047};
5048
5049static const struct nla_policy
5050wlan_hdd_tdls_config_get_status_policy[
5051 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5052{
5053 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
5054 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5055 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305056 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5057 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5058 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305059
5060};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305061
5062static const struct nla_policy
5063wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5064{
5065 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
5066};
5067
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305068static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305069 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305070 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305071 int data_len)
5072{
5073
5074 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5075 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5076
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305077 ENTER();
5078
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305079 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305080 return -EINVAL;
5081 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305082 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305083 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305084 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305085 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305086 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305087 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305088 return -ENOTSUPP;
5089 }
5090
5091 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5092 data, data_len, wlan_hdd_mac_config)) {
5093 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5094 return -EINVAL;
5095 }
5096
5097 /* Parse and fetch mac address */
5098 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5099 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5100 return -EINVAL;
5101 }
5102
5103 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5104 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5105 VOS_MAC_ADDR_LAST_3_BYTES);
5106
Siddharth Bhal76972212014-10-15 16:22:51 +05305107 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5108
5109 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305110 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5111 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305112 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5113 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5114 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5115 {
5116 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5117 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5118 VOS_MAC_ADDRESS_LEN);
5119 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305120 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305121
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305122 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5123 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305124
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305125 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305126 return 0;
5127}
5128
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305129static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5130 struct wireless_dev *wdev,
5131 const void *data,
5132 int data_len)
5133{
5134 int ret = 0;
5135
5136 vos_ssr_protect(__func__);
5137 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5138 vos_ssr_unprotect(__func__);
5139
5140 return ret;
5141}
5142
5143static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305144 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305145 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305146 int data_len)
5147{
5148 u8 peer[6] = {0};
5149 struct net_device *dev = wdev->netdev;
5150 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5151 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5152 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5153 eHalStatus ret;
5154 tANI_S32 state;
5155 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305156 tANI_S32 global_operating_class = 0;
5157 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305158 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305159 int retVal;
5160
5161 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305162
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305163 if (!pAdapter) {
5164 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5165 return -EINVAL;
5166 }
5167
Atul Mittal115287b2014-07-08 13:26:33 +05305168 ret = wlan_hdd_validate_context(pHddCtx);
5169 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305170 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305171 return -EINVAL;
5172 }
5173 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305174 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305175 return -ENOTSUPP;
5176 }
5177 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5178 data, data_len,
5179 wlan_hdd_tdls_config_get_status_policy)) {
5180 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5181 return -EINVAL;
5182 }
5183
5184 /* Parse and fetch mac address */
5185 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5186 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5187 return -EINVAL;
5188 }
5189
5190 memcpy(peer, nla_data(
5191 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5192 sizeof(peer));
5193 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5194
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305195 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305196
Atul Mittal115287b2014-07-08 13:26:33 +05305197 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305198 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305199 NLMSG_HDRLEN);
5200
5201 if (!skb) {
5202 hddLog(VOS_TRACE_LEVEL_ERROR,
5203 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5204 return -EINVAL;
5205 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305206 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 +05305207 reason,
5208 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305209 global_operating_class,
5210 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305211 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305212 if (nla_put_s32(skb,
5213 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5214 state) ||
5215 nla_put_s32(skb,
5216 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5217 reason) ||
5218 nla_put_s32(skb,
5219 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5220 global_operating_class) ||
5221 nla_put_s32(skb,
5222 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5223 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305224
5225 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5226 goto nla_put_failure;
5227 }
5228
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305229 retVal = cfg80211_vendor_cmd_reply(skb);
5230 EXIT();
5231 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305232
5233nla_put_failure:
5234 kfree_skb(skb);
5235 return -EINVAL;
5236}
5237
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305238static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5239 struct wireless_dev *wdev,
5240 const void *data,
5241 int data_len)
5242{
5243 int ret = 0;
5244
5245 vos_ssr_protect(__func__);
5246 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5247 vos_ssr_unprotect(__func__);
5248
5249 return ret;
5250}
5251
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305252static int wlan_hdd_cfg80211_exttdls_callback(
5253#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5254 const tANI_U8* mac,
5255#else
5256 tANI_U8* mac,
5257#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305258 tANI_S32 state,
5259 tANI_S32 reason,
5260 void *ctx)
5261{
5262 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305263 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305264 tANI_S32 global_operating_class = 0;
5265 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305266 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305267
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305268 ENTER();
5269
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305270 if (!pAdapter) {
5271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5272 return -EINVAL;
5273 }
5274
5275 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305276 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305277 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305278 return -EINVAL;
5279 }
5280
5281 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305282 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305283 return -ENOTSUPP;
5284 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305285 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5286#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5287 NULL,
5288#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305289 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5290 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5291 GFP_KERNEL);
5292
5293 if (!skb) {
5294 hddLog(VOS_TRACE_LEVEL_ERROR,
5295 FL("cfg80211_vendor_event_alloc failed"));
5296 return -EINVAL;
5297 }
5298 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305299 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5300 reason,
5301 state,
5302 global_operating_class,
5303 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305304 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5305 MAC_ADDR_ARRAY(mac));
5306
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305307 if (nla_put(skb,
5308 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5309 VOS_MAC_ADDR_SIZE, mac) ||
5310 nla_put_s32(skb,
5311 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5312 state) ||
5313 nla_put_s32(skb,
5314 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5315 reason) ||
5316 nla_put_s32(skb,
5317 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5318 channel) ||
5319 nla_put_s32(skb,
5320 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5321 global_operating_class)
5322 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5324 goto nla_put_failure;
5325 }
5326
5327 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305328 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305329 return (0);
5330
5331nla_put_failure:
5332 kfree_skb(skb);
5333 return -EINVAL;
5334}
5335
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305336static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305337 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305338 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305339 int data_len)
5340{
5341 u8 peer[6] = {0};
5342 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305343 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5344 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5345 eHalStatus status;
5346 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305347 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305348 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305349
5350 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305351
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305352 if (!dev) {
5353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5354 return -EINVAL;
5355 }
5356
5357 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5358 if (!pAdapter) {
5359 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5360 return -EINVAL;
5361 }
5362
Atul Mittal115287b2014-07-08 13:26:33 +05305363 status = wlan_hdd_validate_context(pHddCtx);
5364 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305365 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305366 return -EINVAL;
5367 }
5368 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305369 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305370 return -ENOTSUPP;
5371 }
5372 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5373 data, data_len,
5374 wlan_hdd_tdls_config_enable_policy)) {
5375 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5376 return -EINVAL;
5377 }
5378
5379 /* Parse and fetch mac address */
5380 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5381 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5382 return -EINVAL;
5383 }
5384
5385 memcpy(peer, nla_data(
5386 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5387 sizeof(peer));
5388 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5389
5390 /* Parse and fetch channel */
5391 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5392 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5393 return -EINVAL;
5394 }
5395 pReqMsg.channel = nla_get_s32(
5396 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5397 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5398
5399 /* Parse and fetch global operating class */
5400 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5401 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5402 return -EINVAL;
5403 }
5404 pReqMsg.global_operating_class = nla_get_s32(
5405 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5406 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5407 pReqMsg.global_operating_class);
5408
5409 /* Parse and fetch latency ms */
5410 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5411 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5412 return -EINVAL;
5413 }
5414 pReqMsg.max_latency_ms = nla_get_s32(
5415 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5416 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5417 pReqMsg.max_latency_ms);
5418
5419 /* Parse and fetch required bandwidth kbps */
5420 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5421 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5422 return -EINVAL;
5423 }
5424
5425 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5426 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5427 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5428 pReqMsg.min_bandwidth_kbps);
5429
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305430 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305431 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305432 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305433 wlan_hdd_cfg80211_exttdls_callback);
5434
5435 EXIT();
5436 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305437}
5438
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305439static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5440 struct wireless_dev *wdev,
5441 const void *data,
5442 int data_len)
5443{
5444 int ret = 0;
5445
5446 vos_ssr_protect(__func__);
5447 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5448 vos_ssr_unprotect(__func__);
5449
5450 return ret;
5451}
5452
5453static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305454 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305455 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305456 int data_len)
5457{
5458 u8 peer[6] = {0};
5459 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305460 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5461 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5462 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305463 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305464 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305465
5466 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305467
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305468 if (!dev) {
5469 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5470 return -EINVAL;
5471 }
5472
5473 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5474 if (!pAdapter) {
5475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5476 return -EINVAL;
5477 }
5478
Atul Mittal115287b2014-07-08 13:26:33 +05305479 status = wlan_hdd_validate_context(pHddCtx);
5480 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305481 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305482 return -EINVAL;
5483 }
5484 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305485 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305486 return -ENOTSUPP;
5487 }
5488 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5489 data, data_len,
5490 wlan_hdd_tdls_config_disable_policy)) {
5491 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5492 return -EINVAL;
5493 }
5494 /* Parse and fetch mac address */
5495 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5496 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5497 return -EINVAL;
5498 }
5499
5500 memcpy(peer, nla_data(
5501 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5502 sizeof(peer));
5503 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5504
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305505 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5506
5507 EXIT();
5508 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305509}
5510
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305511static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5512 struct wireless_dev *wdev,
5513 const void *data,
5514 int data_len)
5515{
5516 int ret = 0;
5517
5518 vos_ssr_protect(__func__);
5519 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5520 vos_ssr_unprotect(__func__);
5521
5522 return ret;
5523}
5524
Dasari Srinivas7875a302014-09-26 17:50:57 +05305525static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305526__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305527 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305528 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305529{
5530 struct net_device *dev = wdev->netdev;
5531 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5532 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5533 struct sk_buff *skb = NULL;
5534 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305535 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305536
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305537 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305538
5539 ret = wlan_hdd_validate_context(pHddCtx);
5540 if (0 != ret)
5541 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305542 return ret;
5543 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305544 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5545 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5546 fset |= WIFI_FEATURE_INFRA;
5547 }
5548
5549 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5550 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5551 fset |= WIFI_FEATURE_INFRA_5G;
5552 }
5553
5554#ifdef WLAN_FEATURE_P2P
5555 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5556 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5557 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5558 fset |= WIFI_FEATURE_P2P;
5559 }
5560#endif
5561
5562 /* Soft-AP is supported currently by default */
5563 fset |= WIFI_FEATURE_SOFT_AP;
5564
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305565 /* HOTSPOT is a supplicant feature, enable it by default */
5566 fset |= WIFI_FEATURE_HOTSPOT;
5567
Dasari Srinivas7875a302014-09-26 17:50:57 +05305568#ifdef WLAN_FEATURE_EXTSCAN
5569 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305570 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5571 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5572 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305573 fset |= WIFI_FEATURE_EXTSCAN;
5574 }
5575#endif
5576
Dasari Srinivas7875a302014-09-26 17:50:57 +05305577 if (sme_IsFeatureSupportedByFW(NAN)) {
5578 hddLog(LOG1, FL("NAN is supported by firmware"));
5579 fset |= WIFI_FEATURE_NAN;
5580 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305581
5582 /* D2D RTT is not supported currently by default */
5583 if (sme_IsFeatureSupportedByFW(RTT)) {
5584 hddLog(LOG1, FL("RTT is supported by firmware"));
5585 fset |= WIFI_FEATURE_D2AP_RTT;
5586 }
5587
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305588 if (sme_IsFeatureSupportedByFW(RTT3)) {
5589 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5590 fset |= WIFI_FEATURE_RTT3;
5591 }
5592
Dasari Srinivas7875a302014-09-26 17:50:57 +05305593#ifdef FEATURE_WLAN_BATCH_SCAN
5594 if (fset & WIFI_FEATURE_EXTSCAN) {
5595 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5596 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5597 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5598 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5599 fset |= WIFI_FEATURE_BATCH_SCAN;
5600 }
5601#endif
5602
5603#ifdef FEATURE_WLAN_SCAN_PNO
5604 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5605 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5606 hddLog(LOG1, FL("PNO is supported by firmware"));
5607 fset |= WIFI_FEATURE_PNO;
5608 }
5609#endif
5610
5611 /* STA+STA is supported currently by default */
5612 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5613
5614#ifdef FEATURE_WLAN_TDLS
5615 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5616 sme_IsFeatureSupportedByFW(TDLS)) {
5617 hddLog(LOG1, FL("TDLS is supported by firmware"));
5618 fset |= WIFI_FEATURE_TDLS;
5619 }
5620
5621 /* TDLS_OFFCHANNEL is not supported currently by default */
5622#endif
5623
5624#ifdef WLAN_AP_STA_CONCURRENCY
5625 /* AP+STA concurrency is supported currently by default */
5626 fset |= WIFI_FEATURE_AP_STA;
5627#endif
5628
Mukul Sharma5add0532015-08-17 15:57:47 +05305629#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5630 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5631 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5632#endif
5633
Dasari Srinivas7875a302014-09-26 17:50:57 +05305634 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5635 NLMSG_HDRLEN);
5636
5637 if (!skb) {
5638 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5639 return -EINVAL;
5640 }
5641 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5642
5643 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5644 hddLog(LOGE, FL("nla put fail"));
5645 goto nla_put_failure;
5646 }
5647
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305648 ret = cfg80211_vendor_cmd_reply(skb);
5649 EXIT();
5650 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305651
5652nla_put_failure:
5653 kfree_skb(skb);
5654 return -EINVAL;
5655}
5656
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305657static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305658wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5659 struct wireless_dev *wdev,
5660 const void *data, int data_len)
5661{
5662 int ret = 0;
5663
5664 vos_ssr_protect(__func__);
5665 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5666 vos_ssr_unprotect(__func__);
5667
5668 return ret;
5669}
5670
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305671
5672static const struct
5673nla_policy
5674qca_wlan_vendor_wifi_logger_get_ring_data_policy
5675[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5676 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5677 = {.type = NLA_U32 },
5678};
5679
5680static int
5681 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5682 struct wireless_dev *wdev,
5683 const void *data,
5684 int data_len)
5685{
5686 int ret;
5687 VOS_STATUS status;
5688 uint32_t ring_id;
5689 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5690 struct nlattr *tb
5691 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5692
5693 ENTER();
5694
5695 ret = wlan_hdd_validate_context(hdd_ctx);
5696 if (0 != ret) {
5697 return ret;
5698 }
5699
5700 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5701 data, data_len,
5702 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5703 hddLog(LOGE, FL("Invalid attribute"));
5704 return -EINVAL;
5705 }
5706
5707 /* Parse and fetch ring id */
5708 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5709 hddLog(LOGE, FL("attr ATTR failed"));
5710 return -EINVAL;
5711 }
5712
5713 ring_id = nla_get_u32(
5714 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5715
5716 hddLog(LOG1, FL("Bug report triggered by framework"));
5717
5718 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5719 WLAN_LOG_INDICATOR_FRAMEWORK,
5720 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305721 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305722 );
5723 if (VOS_STATUS_SUCCESS != status) {
5724 hddLog(LOGE, FL("Failed to trigger bug report"));
5725
5726 return -EINVAL;
5727 }
5728
5729 return 0;
5730
5731
5732}
5733
5734
5735static int
5736 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5737 struct wireless_dev *wdev,
5738 const void *data,
5739 int data_len)
5740{
5741 int ret = 0;
5742
5743 vos_ssr_protect(__func__);
5744 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5745 wdev, data, data_len);
5746 vos_ssr_unprotect(__func__);
5747
5748 return ret;
5749
5750}
5751
5752
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305753static int
5754__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305755 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305756 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305757{
5758 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5759 uint8_t i, feature_sets, max_feature_sets;
5760 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5761 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305762 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5763 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305764
5765 ENTER();
5766
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305767 ret = wlan_hdd_validate_context(pHddCtx);
5768 if (0 != ret)
5769 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305770 return ret;
5771 }
5772
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305773 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5774 data, data_len, NULL)) {
5775 hddLog(LOGE, FL("Invalid ATTR"));
5776 return -EINVAL;
5777 }
5778
5779 /* Parse and fetch max feature set */
5780 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5781 hddLog(LOGE, FL("Attr max feature set size failed"));
5782 return -EINVAL;
5783 }
5784 max_feature_sets = nla_get_u32(
5785 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5786 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5787
5788 /* Fill feature combination matrix */
5789 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305790 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5791 WIFI_FEATURE_P2P;
5792
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305793 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5794 WIFI_FEATURE_SOFT_AP;
5795
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305796 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5797 WIFI_FEATURE_SOFT_AP;
5798
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305799 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5800 WIFI_FEATURE_SOFT_AP |
5801 WIFI_FEATURE_P2P;
5802
5803 /* Add more feature combinations here */
5804
5805 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5806 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5807 hddLog(LOG1, "Feature set matrix");
5808 for (i = 0; i < feature_sets; i++)
5809 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5810
5811 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5812 sizeof(u32) * feature_sets +
5813 NLMSG_HDRLEN);
5814
5815 if (reply_skb) {
5816 if (nla_put_u32(reply_skb,
5817 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5818 feature_sets) ||
5819 nla_put(reply_skb,
5820 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5821 sizeof(u32) * feature_sets, feature_set_matrix)) {
5822 hddLog(LOGE, FL("nla put fail"));
5823 kfree_skb(reply_skb);
5824 return -EINVAL;
5825 }
5826
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305827 ret = cfg80211_vendor_cmd_reply(reply_skb);
5828 EXIT();
5829 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305830 }
5831 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5832 return -ENOMEM;
5833
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305834}
5835
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305836static int
5837wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5838 struct wireless_dev *wdev,
5839 const void *data, int data_len)
5840{
5841 int ret = 0;
5842
5843 vos_ssr_protect(__func__);
5844 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5845 data_len);
5846 vos_ssr_unprotect(__func__);
5847
5848 return ret;
5849}
5850
c_manjeecfd1efb2015-09-25 19:32:34 +05305851
5852static int
5853__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5854 struct wireless_dev *wdev,
5855 const void *data, int data_len)
5856{
5857 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5858 int ret;
5859 ENTER();
5860
5861 ret = wlan_hdd_validate_context(pHddCtx);
5862 if (0 != ret)
5863 {
5864 return ret;
5865 }
5866
5867 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5868 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5869 {
5870 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5871 return -EINVAL;
5872 }
5873 /*call common API for FW mem dump req*/
5874 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5875
Abhishek Singhc783fa72015-12-09 18:07:34 +05305876 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305877 {
5878 /*indicate to userspace the status of fw mem dump */
5879 wlan_indicate_mem_dump_complete(true);
5880 }
5881 else
5882 {
5883 /*else send failure to userspace */
5884 wlan_indicate_mem_dump_complete(false);
5885 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305886 EXIT();
5887 return ret;
5888}
5889
5890/**
5891 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5892 * @wiphy: pointer to wireless wiphy structure.
5893 * @wdev: pointer to wireless_dev structure.
5894 * @data: Pointer to the NL data.
5895 * @data_len:Length of @data
5896 *
5897 * This is called when wlan driver needs to get the firmware memory dump
5898 * via vendor specific command.
5899 *
5900 * Return: 0 on success, error number otherwise.
5901 */
5902
5903static int
5904wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5905 struct wireless_dev *wdev,
5906 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305907{
5908 int ret = 0;
5909 vos_ssr_protect(__func__);
5910 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5911 data_len);
5912 vos_ssr_unprotect(__func__);
5913 return ret;
5914}
c_manjeecfd1efb2015-09-25 19:32:34 +05305915
Sushant Kaushik8e644982015-09-23 12:18:54 +05305916static const struct
5917nla_policy
5918qca_wlan_vendor_wifi_logger_start_policy
5919[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5920 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5921 = {.type = NLA_U32 },
5922 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5923 = {.type = NLA_U32 },
5924 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5925 = {.type = NLA_U32 },
5926};
5927
5928/**
5929 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5930 * or disable the collection of packet statistics from the firmware
5931 * @wiphy: WIPHY structure pointer
5932 * @wdev: Wireless device structure pointer
5933 * @data: Pointer to the data received
5934 * @data_len: Length of the data received
5935 *
5936 * This function is used to enable or disable the collection of packet
5937 * statistics from the firmware
5938 *
5939 * Return: 0 on success and errno on failure
5940 */
5941static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5942 struct wireless_dev *wdev,
5943 const void *data,
5944 int data_len)
5945{
5946 eHalStatus status;
5947 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5948 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5949 tAniWifiStartLog start_log;
5950
5951 status = wlan_hdd_validate_context(hdd_ctx);
5952 if (0 != status) {
5953 return -EINVAL;
5954 }
5955
5956 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5957 data, data_len,
5958 qca_wlan_vendor_wifi_logger_start_policy)) {
5959 hddLog(LOGE, FL("Invalid attribute"));
5960 return -EINVAL;
5961 }
5962
5963 /* Parse and fetch ring id */
5964 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5965 hddLog(LOGE, FL("attr ATTR failed"));
5966 return -EINVAL;
5967 }
5968 start_log.ringId = nla_get_u32(
5969 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5970 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5971
5972 /* Parse and fetch verbose level */
5973 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5974 hddLog(LOGE, FL("attr verbose_level failed"));
5975 return -EINVAL;
5976 }
5977 start_log.verboseLevel = nla_get_u32(
5978 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5979 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5980
5981 /* Parse and fetch flag */
5982 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5983 hddLog(LOGE, FL("attr flag failed"));
5984 return -EINVAL;
5985 }
5986 start_log.flag = nla_get_u32(
5987 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5988 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5989
5990 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305991 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5992 !vos_isPktStatsEnabled()))
5993
Sushant Kaushik8e644982015-09-23 12:18:54 +05305994 {
5995 hddLog(LOGE, FL("per pkt stats not enabled"));
5996 return -EINVAL;
5997 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305998
Sushant Kaushik33200572015-08-05 16:46:20 +05305999 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306000 return 0;
6001}
6002
6003/**
6004 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6005 * or disable the collection of packet statistics from the firmware
6006 * @wiphy: WIPHY structure pointer
6007 * @wdev: Wireless device structure pointer
6008 * @data: Pointer to the data received
6009 * @data_len: Length of the data received
6010 *
6011 * This function is used to enable or disable the collection of packet
6012 * statistics from the firmware
6013 *
6014 * Return: 0 on success and errno on failure
6015 */
6016static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6017 struct wireless_dev *wdev,
6018 const void *data,
6019 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306020{
6021 int ret = 0;
6022
6023 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306024
6025 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6026 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306027 vos_ssr_unprotect(__func__);
6028
6029 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306030}
6031
6032
Agarwal Ashish738843c2014-09-25 12:27:56 +05306033static const struct nla_policy
6034wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6035 +1] =
6036{
6037 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6038};
6039
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306040static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306041 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306042 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306043 int data_len)
6044{
6045 struct net_device *dev = wdev->netdev;
6046 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6047 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6048 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6049 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6050 eHalStatus status;
6051 u32 dfsFlag = 0;
6052
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306053 ENTER();
6054
Agarwal Ashish738843c2014-09-25 12:27:56 +05306055 status = wlan_hdd_validate_context(pHddCtx);
6056 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306057 return -EINVAL;
6058 }
6059 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6060 data, data_len,
6061 wlan_hdd_set_no_dfs_flag_config_policy)) {
6062 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6063 return -EINVAL;
6064 }
6065
6066 /* Parse and fetch required bandwidth kbps */
6067 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6068 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6069 return -EINVAL;
6070 }
6071
6072 dfsFlag = nla_get_u32(
6073 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6074 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6075 dfsFlag);
6076
6077 pHddCtx->disable_dfs_flag = dfsFlag;
6078
6079 sme_disable_dfs_channel(hHal, dfsFlag);
6080 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306081
6082 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306083 return 0;
6084}
Atul Mittal115287b2014-07-08 13:26:33 +05306085
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306086static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6087 struct wireless_dev *wdev,
6088 const void *data,
6089 int data_len)
6090{
6091 int ret = 0;
6092
6093 vos_ssr_protect(__func__);
6094 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6095 vos_ssr_unprotect(__func__);
6096
6097 return ret;
6098
6099}
6100
Mukul Sharma2a271632014-10-13 14:59:01 +05306101const struct
6102nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6103{
6104 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6105 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6106};
6107
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306108static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306109 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306110{
6111
6112 u8 bssid[6] = {0};
6113 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6114 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6115 eHalStatus status = eHAL_STATUS_SUCCESS;
6116 v_U32_t isFwrRoamEnabled = FALSE;
6117 int ret;
6118
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306119 ENTER();
6120
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306121 ret = wlan_hdd_validate_context(pHddCtx);
6122 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306123 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306124 }
6125
6126 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6127 data, data_len,
6128 qca_wlan_vendor_attr);
6129 if (ret){
6130 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6131 return -EINVAL;
6132 }
6133
6134 /* Parse and fetch Enable flag */
6135 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6136 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6137 return -EINVAL;
6138 }
6139
6140 isFwrRoamEnabled = nla_get_u32(
6141 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6142
6143 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6144
6145 /* Parse and fetch bssid */
6146 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6147 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6148 return -EINVAL;
6149 }
6150
6151 memcpy(bssid, nla_data(
6152 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6153 sizeof(bssid));
6154 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6155
6156 //Update roaming
6157 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306158 if (!HAL_STATUS_SUCCESS(status)) {
6159 hddLog(LOGE,
6160 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6161 return -EINVAL;
6162 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306163 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306164 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306165}
6166
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306167static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6168 struct wireless_dev *wdev, const void *data, int data_len)
6169{
6170 int ret = 0;
6171
6172 vos_ssr_protect(__func__);
6173 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6174 vos_ssr_unprotect(__func__);
6175
6176 return ret;
6177}
6178
Sushant Kaushik847890c2015-09-28 16:05:17 +05306179static const struct
6180nla_policy
6181qca_wlan_vendor_get_wifi_info_policy[
6182 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6183 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6184 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6185};
6186
6187
6188/**
6189 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6190 * @wiphy: pointer to wireless wiphy structure.
6191 * @wdev: pointer to wireless_dev structure.
6192 * @data: Pointer to the data to be passed via vendor interface
6193 * @data_len:Length of the data to be passed
6194 *
6195 * This is called when wlan driver needs to send wifi driver related info
6196 * (driver/fw version) to the user space application upon request.
6197 *
6198 * Return: Return the Success or Failure code.
6199 */
6200static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6201 struct wireless_dev *wdev,
6202 const void *data, int data_len)
6203{
6204 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6205 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6206 tSirVersionString version;
6207 uint32 version_len;
6208 uint8 attr;
6209 int status;
6210 struct sk_buff *reply_skb = NULL;
6211
6212 if (VOS_FTM_MODE == hdd_get_conparam()) {
6213 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6214 return -EINVAL;
6215 }
6216
6217 status = wlan_hdd_validate_context(hdd_ctx);
6218 if (0 != status) {
6219 hddLog(LOGE, FL("HDD context is not valid"));
6220 return -EINVAL;
6221 }
6222
6223 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6224 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6225 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6226 return -EINVAL;
6227 }
6228
6229 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6230 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6231 QWLAN_VERSIONSTR);
6232 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6233 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6234 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6235 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6236 hdd_ctx->fw_Version);
6237 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6238 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6239 } else {
6240 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6241 return -EINVAL;
6242 }
6243
6244 version_len = strlen(version);
6245 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6246 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6247 if (!reply_skb) {
6248 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6249 return -ENOMEM;
6250 }
6251
6252 if (nla_put(reply_skb, attr, version_len, version)) {
6253 hddLog(LOGE, FL("nla put fail"));
6254 kfree_skb(reply_skb);
6255 return -EINVAL;
6256 }
6257
6258 return cfg80211_vendor_cmd_reply(reply_skb);
6259}
6260
6261/**
6262 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6263 * @wiphy: pointer to wireless wiphy structure.
6264 * @wdev: pointer to wireless_dev structure.
6265 * @data: Pointer to the data to be passed via vendor interface
6266 * @data_len:Length of the data to be passed
6267 * @data_len: Length of the data received
6268 *
6269 * This function is used to enable or disable the collection of packet
6270 * statistics from the firmware
6271 *
6272 * Return: 0 on success and errno on failure
6273 */
6274
6275static int
6276wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6277 struct wireless_dev *wdev,
6278 const void *data, int data_len)
6279
6280
6281{
6282 int ret = 0;
6283
6284 vos_ssr_protect(__func__);
6285 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6286 wdev, data, data_len);
6287 vos_ssr_unprotect(__func__);
6288
6289 return ret;
6290}
6291
6292
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306293/*
6294 * define short names for the global vendor params
6295 * used by __wlan_hdd_cfg80211_monitor_rssi()
6296 */
6297#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6298#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6299#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6300#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6301#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6302
6303/**---------------------------------------------------------------------------
6304
6305 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6306 monitor start is completed successfully.
6307
6308 \return - None
6309
6310 --------------------------------------------------------------------------*/
6311void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6312{
6313 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6314
6315 if (NULL == pHddCtx)
6316 {
6317 hddLog(VOS_TRACE_LEVEL_ERROR,
6318 "%s: HDD context is NULL",__func__);
6319 return;
6320 }
6321
6322 if (VOS_STATUS_SUCCESS == status)
6323 {
6324 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6325 }
6326 else
6327 {
6328 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6329 }
6330
6331 return;
6332}
6333
6334/**---------------------------------------------------------------------------
6335
6336 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6337 stop is completed successfully.
6338
6339 \return - None
6340
6341 --------------------------------------------------------------------------*/
6342void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6343{
6344 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6345
6346 if (NULL == pHddCtx)
6347 {
6348 hddLog(VOS_TRACE_LEVEL_ERROR,
6349 "%s: HDD context is NULL",__func__);
6350 return;
6351 }
6352
6353 if (VOS_STATUS_SUCCESS == status)
6354 {
6355 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6356 }
6357 else
6358 {
6359 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6360 }
6361
6362 return;
6363}
6364
6365/**
6366 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6367 * @wiphy: Pointer to wireless phy
6368 * @wdev: Pointer to wireless device
6369 * @data: Pointer to data
6370 * @data_len: Data length
6371 *
6372 * Return: 0 on success, negative errno on failure
6373 */
6374
6375static int
6376__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6377 struct wireless_dev *wdev,
6378 const void *data,
6379 int data_len)
6380{
6381 struct net_device *dev = wdev->netdev;
6382 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6383 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6384 hdd_station_ctx_t *pHddStaCtx;
6385 struct nlattr *tb[PARAM_MAX + 1];
6386 tpSirRssiMonitorReq pReq;
6387 eHalStatus status;
6388 int ret;
6389 uint32_t control;
6390 static const struct nla_policy policy[PARAM_MAX + 1] = {
6391 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6392 [PARAM_CONTROL] = { .type = NLA_U32 },
6393 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6394 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6395 };
6396
6397 ENTER();
6398
6399 ret = wlan_hdd_validate_context(hdd_ctx);
6400 if (0 != ret) {
6401 return -EINVAL;
6402 }
6403
6404 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6405 hddLog(LOGE, FL("Not in Connected state!"));
6406 return -ENOTSUPP;
6407 }
6408
6409 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6410 hddLog(LOGE, FL("Invalid ATTR"));
6411 return -EINVAL;
6412 }
6413
6414 if (!tb[PARAM_REQUEST_ID]) {
6415 hddLog(LOGE, FL("attr request id failed"));
6416 return -EINVAL;
6417 }
6418
6419 if (!tb[PARAM_CONTROL]) {
6420 hddLog(LOGE, FL("attr control failed"));
6421 return -EINVAL;
6422 }
6423
6424 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6425
6426 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6427 if(NULL == pReq)
6428 {
6429 hddLog(LOGE,
6430 FL("vos_mem_alloc failed "));
6431 return eHAL_STATUS_FAILED_ALLOC;
6432 }
6433 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6434
6435 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6436 pReq->sessionId = pAdapter->sessionId;
6437 pReq->rssiMonitorCbContext = hdd_ctx;
6438 control = nla_get_u32(tb[PARAM_CONTROL]);
6439 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6440
6441 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6442 pReq->requestId, pReq->sessionId, control);
6443
6444 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6445 if (!tb[PARAM_MIN_RSSI]) {
6446 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306447 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306448 }
6449
6450 if (!tb[PARAM_MAX_RSSI]) {
6451 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306452 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306453 }
6454
6455 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6456 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6457 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6458
6459 if (!(pReq->minRssi < pReq->maxRssi)) {
6460 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6461 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306462 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306463 }
6464 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6465 pReq->minRssi, pReq->maxRssi);
6466 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6467
6468 }
6469 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6470 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6471 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6472 }
6473 else {
6474 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306475 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306476 }
6477
6478 if (!HAL_STATUS_SUCCESS(status)) {
6479 hddLog(LOGE,
6480 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306481 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306482 }
6483
6484 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306485fail:
6486 vos_mem_free(pReq);
6487 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306488}
6489
6490/*
6491 * done with short names for the global vendor params
6492 * used by __wlan_hdd_cfg80211_monitor_rssi()
6493 */
6494#undef PARAM_MAX
6495#undef PARAM_CONTROL
6496#undef PARAM_REQUEST_ID
6497#undef PARAM_MAX_RSSI
6498#undef PARAM_MIN_RSSI
6499
6500/**
6501 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6502 * @wiphy: wiphy structure pointer
6503 * @wdev: Wireless device structure pointer
6504 * @data: Pointer to the data received
6505 * @data_len: Length of @data
6506 *
6507 * Return: 0 on success; errno on failure
6508 */
6509static int
6510wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6511 const void *data, int data_len)
6512{
6513 int ret;
6514
6515 vos_ssr_protect(__func__);
6516 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6517 vos_ssr_unprotect(__func__);
6518
6519 return ret;
6520}
6521
6522/**
6523 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6524 * @hddctx: HDD context
6525 * @data: rssi breached event data
6526 *
6527 * This function reads the rssi breached event %data and fill in the skb with
6528 * NL attributes and send up the NL event.
6529 * This callback execute in atomic context and must not invoke any
6530 * blocking calls.
6531 *
6532 * Return: none
6533 */
6534void hdd_rssi_threshold_breached_cb(void *hddctx,
6535 struct rssi_breach_event *data)
6536{
6537 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6538 int status;
6539 struct sk_buff *skb;
6540
6541 ENTER();
6542 status = wlan_hdd_validate_context(pHddCtx);
6543
6544 if (0 != status) {
6545 return;
6546 }
6547
6548 if (!data) {
6549 hddLog(LOGE, FL("data is null"));
6550 return;
6551 }
6552
6553 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6554#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6555 NULL,
6556#endif
6557 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6558 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6559 GFP_KERNEL);
6560
6561 if (!skb) {
6562 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6563 return;
6564 }
6565
6566 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6567 data->request_id, data->curr_rssi);
6568 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6569 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6570
6571 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6572 data->request_id) ||
6573 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6574 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6575 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6576 data->curr_rssi)) {
6577 hddLog(LOGE, FL("nla put fail"));
6578 goto fail;
6579 }
6580
6581 cfg80211_vendor_event(skb, GFP_KERNEL);
6582 return;
6583
6584fail:
6585 kfree_skb(skb);
6586 return;
6587}
6588
6589
6590
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306591/**
6592 * __wlan_hdd_cfg80211_setband() - set band
6593 * @wiphy: Pointer to wireless phy
6594 * @wdev: Pointer to wireless device
6595 * @data: Pointer to data
6596 * @data_len: Data length
6597 *
6598 * Return: 0 on success, negative errno on failure
6599 */
6600static int
6601__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6602 struct wireless_dev *wdev,
6603 const void *data,
6604 int data_len)
6605{
6606 struct net_device *dev = wdev->netdev;
6607 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6608 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6609 int ret;
6610 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6611 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6612
6613 ENTER();
6614
6615 ret = wlan_hdd_validate_context(hdd_ctx);
6616 if (0 != ret) {
6617 hddLog(LOGE, FL("HDD context is not valid"));
6618 return ret;
6619 }
6620
6621 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6622 policy)) {
6623 hddLog(LOGE, FL("Invalid ATTR"));
6624 return -EINVAL;
6625 }
6626
6627 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6628 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6629 return -EINVAL;
6630 }
6631
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306632 hdd_ctx->isSetBandByNL = TRUE;
6633 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306634 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306635 hdd_ctx->isSetBandByNL = FALSE;
6636
6637 EXIT();
6638 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306639}
6640
6641/**
6642 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6643 * @wiphy: wiphy structure pointer
6644 * @wdev: Wireless device structure pointer
6645 * @data: Pointer to the data received
6646 * @data_len: Length of @data
6647 *
6648 * Return: 0 on success; errno on failure
6649 */
6650static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6651 struct wireless_dev *wdev,
6652 const void *data,
6653 int data_len)
6654{
6655 int ret = 0;
6656
6657 vos_ssr_protect(__func__);
6658 ret = __wlan_hdd_cfg80211_setband(wiphy,
6659 wdev, data, data_len);
6660 vos_ssr_unprotect(__func__);
6661
6662 return ret;
6663}
6664
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306665#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6666/**
6667 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6668 * @hdd_ctx: HDD context
6669 * @request_id: [input] request id
6670 * @pattern_id: [output] pattern id
6671 *
6672 * This function loops through request id to pattern id array
6673 * if the slot is available, store the request id and return pattern id
6674 * if entry exists, return the pattern id
6675 *
6676 * Return: 0 on success and errno on failure
6677 */
6678static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6679 uint32_t request_id,
6680 uint8_t *pattern_id)
6681{
6682 uint32_t i;
6683
6684 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6685 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6686 {
6687 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6688 {
6689 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6690 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6691 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6692 return 0;
6693 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6694 request_id) {
6695 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6696 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6697 return 0;
6698 }
6699 }
6700 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6701 return -EINVAL;
6702}
6703
6704/**
6705 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6706 * @hdd_ctx: HDD context
6707 * @request_id: [input] request id
6708 * @pattern_id: [output] pattern id
6709 *
6710 * This function loops through request id to pattern id array
6711 * reset request id to 0 (slot available again) and
6712 * return pattern id
6713 *
6714 * Return: 0 on success and errno on failure
6715 */
6716static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6717 uint32_t request_id,
6718 uint8_t *pattern_id)
6719{
6720 uint32_t i;
6721
6722 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6723 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6724 {
6725 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6726 {
6727 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6728 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6729 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6730 return 0;
6731 }
6732 }
6733 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6734 return -EINVAL;
6735}
6736
6737
6738/*
6739 * define short names for the global vendor params
6740 * used by __wlan_hdd_cfg80211_offloaded_packets()
6741 */
6742#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6743#define PARAM_REQUEST_ID \
6744 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6745#define PARAM_CONTROL \
6746 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6747#define PARAM_IP_PACKET \
6748 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6749#define PARAM_SRC_MAC_ADDR \
6750 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6751#define PARAM_DST_MAC_ADDR \
6752 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6753#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6754
6755/**
6756 * wlan_hdd_add_tx_ptrn() - add tx pattern
6757 * @adapter: adapter pointer
6758 * @hdd_ctx: hdd context
6759 * @tb: nl attributes
6760 *
6761 * This function reads the NL attributes and forms a AddTxPtrn message
6762 * posts it to SME.
6763 *
6764 */
6765static int
6766wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6767 struct nlattr **tb)
6768{
6769 struct sSirAddPeriodicTxPtrn *add_req;
6770 eHalStatus status;
6771 uint32_t request_id, ret, len;
6772 uint8_t pattern_id = 0;
6773 v_MACADDR_t dst_addr;
6774 uint16_t eth_type = htons(ETH_P_IP);
6775
6776 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6777 {
6778 hddLog(LOGE, FL("Not in Connected state!"));
6779 return -ENOTSUPP;
6780 }
6781
6782 add_req = vos_mem_malloc(sizeof(*add_req));
6783 if (!add_req)
6784 {
6785 hddLog(LOGE, FL("memory allocation failed"));
6786 return -ENOMEM;
6787 }
6788
6789 /* Parse and fetch request Id */
6790 if (!tb[PARAM_REQUEST_ID])
6791 {
6792 hddLog(LOGE, FL("attr request id failed"));
6793 goto fail;
6794 }
6795
6796 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6797 hddLog(LOG1, FL("Request Id: %u"), request_id);
6798 if (request_id == 0)
6799 {
6800 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306801 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306802 }
6803
6804 if (!tb[PARAM_PERIOD])
6805 {
6806 hddLog(LOGE, FL("attr period failed"));
6807 goto fail;
6808 }
6809 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6810 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6811 if (add_req->usPtrnIntervalMs == 0)
6812 {
6813 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6814 goto fail;
6815 }
6816
6817 if (!tb[PARAM_SRC_MAC_ADDR])
6818 {
6819 hddLog(LOGE, FL("attr source mac address failed"));
6820 goto fail;
6821 }
6822 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6823 VOS_MAC_ADDR_SIZE);
6824 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6825 MAC_ADDR_ARRAY(add_req->macAddress));
6826
6827 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6828 VOS_MAC_ADDR_SIZE))
6829 {
6830 hddLog(LOGE,
6831 FL("input src mac address and connected ap bssid are different"));
6832 goto fail;
6833 }
6834
6835 if (!tb[PARAM_DST_MAC_ADDR])
6836 {
6837 hddLog(LOGE, FL("attr dst mac address failed"));
6838 goto fail;
6839 }
6840 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6841 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6842 MAC_ADDR_ARRAY(dst_addr.bytes));
6843
6844 if (!tb[PARAM_IP_PACKET])
6845 {
6846 hddLog(LOGE, FL("attr ip packet failed"));
6847 goto fail;
6848 }
6849 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6850 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6851
6852 if (add_req->ucPtrnSize < 0 ||
6853 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6854 HDD_ETH_HEADER_LEN))
6855 {
6856 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6857 add_req->ucPtrnSize);
6858 goto fail;
6859 }
6860
6861 len = 0;
6862 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6863 len += VOS_MAC_ADDR_SIZE;
6864 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6865 VOS_MAC_ADDR_SIZE);
6866 len += VOS_MAC_ADDR_SIZE;
6867 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6868 len += 2;
6869
6870 /*
6871 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6872 * ------------------------------------------------------------
6873 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6874 * ------------------------------------------------------------
6875 */
6876 vos_mem_copy(&add_req->ucPattern[len],
6877 nla_data(tb[PARAM_IP_PACKET]),
6878 add_req->ucPtrnSize);
6879 add_req->ucPtrnSize += len;
6880
6881 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6882 add_req->ucPattern, add_req->ucPtrnSize);
6883
6884 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6885 if (ret)
6886 {
6887 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6888 goto fail;
6889 }
6890 add_req->ucPtrnId = pattern_id;
6891 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6892
6893 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6894 if (!HAL_STATUS_SUCCESS(status))
6895 {
6896 hddLog(LOGE,
6897 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6898 goto fail;
6899 }
6900
6901 EXIT();
6902 vos_mem_free(add_req);
6903 return 0;
6904
6905fail:
6906 vos_mem_free(add_req);
6907 return -EINVAL;
6908}
6909
6910/**
6911 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6912 * @adapter: adapter pointer
6913 * @hdd_ctx: hdd context
6914 * @tb: nl attributes
6915 *
6916 * This function reads the NL attributes and forms a DelTxPtrn message
6917 * posts it to SME.
6918 *
6919 */
6920static int
6921wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6922 struct nlattr **tb)
6923{
6924 struct sSirDelPeriodicTxPtrn *del_req;
6925 eHalStatus status;
6926 uint32_t request_id, ret;
6927 uint8_t pattern_id = 0;
6928
6929 /* Parse and fetch request Id */
6930 if (!tb[PARAM_REQUEST_ID])
6931 {
6932 hddLog(LOGE, FL("attr request id failed"));
6933 return -EINVAL;
6934 }
6935 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6936 if (request_id == 0)
6937 {
6938 hddLog(LOGE, FL("request_id cannot be zero"));
6939 return -EINVAL;
6940 }
6941
6942 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6943 if (ret)
6944 {
6945 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6946 return -EINVAL;
6947 }
6948
6949 del_req = vos_mem_malloc(sizeof(*del_req));
6950 if (!del_req)
6951 {
6952 hddLog(LOGE, FL("memory allocation failed"));
6953 return -ENOMEM;
6954 }
6955
6956 vos_mem_set(del_req, sizeof(*del_req), 0);
6957 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6958 VOS_MAC_ADDR_SIZE);
6959 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6960 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6961 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6962 request_id, pattern_id, del_req->ucPatternIdBitmap);
6963
6964 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6965 if (!HAL_STATUS_SUCCESS(status))
6966 {
6967 hddLog(LOGE,
6968 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6969 goto fail;
6970 }
6971
6972 EXIT();
6973 vos_mem_free(del_req);
6974 return 0;
6975
6976fail:
6977 vos_mem_free(del_req);
6978 return -EINVAL;
6979}
6980
6981
6982/**
6983 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6984 * @wiphy: Pointer to wireless phy
6985 * @wdev: Pointer to wireless device
6986 * @data: Pointer to data
6987 * @data_len: Data length
6988 *
6989 * Return: 0 on success, negative errno on failure
6990 */
6991static int
6992__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6993 struct wireless_dev *wdev,
6994 const void *data,
6995 int data_len)
6996{
6997 struct net_device *dev = wdev->netdev;
6998 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6999 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7000 struct nlattr *tb[PARAM_MAX + 1];
7001 uint8_t control;
7002 int ret;
7003 static const struct nla_policy policy[PARAM_MAX + 1] =
7004 {
7005 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7006 [PARAM_CONTROL] = { .type = NLA_U32 },
7007 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7008 .len = VOS_MAC_ADDR_SIZE },
7009 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7010 .len = VOS_MAC_ADDR_SIZE },
7011 [PARAM_PERIOD] = { .type = NLA_U32 },
7012 };
7013
7014 ENTER();
7015
7016 ret = wlan_hdd_validate_context(hdd_ctx);
7017 if (0 != ret)
7018 {
7019 hddLog(LOGE, FL("HDD context is not valid"));
7020 return ret;
7021 }
7022
7023 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7024 {
7025 hddLog(LOGE,
7026 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7027 return -ENOTSUPP;
7028 }
7029
7030 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7031 {
7032 hddLog(LOGE, FL("Invalid ATTR"));
7033 return -EINVAL;
7034 }
7035
7036 if (!tb[PARAM_CONTROL])
7037 {
7038 hddLog(LOGE, FL("attr control failed"));
7039 return -EINVAL;
7040 }
7041 control = nla_get_u32(tb[PARAM_CONTROL]);
7042 hddLog(LOG1, FL("Control: %d"), control);
7043
7044 if (control == WLAN_START_OFFLOADED_PACKETS)
7045 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7046 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7047 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7048 else
7049 {
7050 hddLog(LOGE, FL("Invalid control: %d"), control);
7051 return -EINVAL;
7052 }
7053}
7054
7055/*
7056 * done with short names for the global vendor params
7057 * used by __wlan_hdd_cfg80211_offloaded_packets()
7058 */
7059#undef PARAM_MAX
7060#undef PARAM_REQUEST_ID
7061#undef PARAM_CONTROL
7062#undef PARAM_IP_PACKET
7063#undef PARAM_SRC_MAC_ADDR
7064#undef PARAM_DST_MAC_ADDR
7065#undef PARAM_PERIOD
7066
7067/**
7068 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7069 * @wiphy: wiphy structure pointer
7070 * @wdev: Wireless device structure pointer
7071 * @data: Pointer to the data received
7072 * @data_len: Length of @data
7073 *
7074 * Return: 0 on success; errno on failure
7075 */
7076static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7077 struct wireless_dev *wdev,
7078 const void *data,
7079 int data_len)
7080{
7081 int ret = 0;
7082
7083 vos_ssr_protect(__func__);
7084 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7085 wdev, data, data_len);
7086 vos_ssr_unprotect(__func__);
7087
7088 return ret;
7089}
7090#endif
7091
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307092static const struct
7093nla_policy
7094qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
7095 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
7096};
7097
7098/**
7099 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7100 * get link properties like nss, rate flags and operating frequency for
7101 * the connection with the given peer.
7102 * @wiphy: WIPHY structure pointer
7103 * @wdev: Wireless device structure pointer
7104 * @data: Pointer to the data received
7105 * @data_len: Length of the data received
7106 *
7107 * This function return the above link properties on success.
7108 *
7109 * Return: 0 on success and errno on failure
7110 */
7111static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7112 struct wireless_dev *wdev,
7113 const void *data,
7114 int data_len)
7115{
7116 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7117 struct net_device *dev = wdev->netdev;
7118 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7119 hdd_station_ctx_t *hdd_sta_ctx;
7120 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7121 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7122 uint32_t sta_id;
7123 struct sk_buff *reply_skb;
7124 uint32_t rate_flags = 0;
7125 uint8_t nss;
7126 uint8_t final_rate_flags = 0;
7127 uint32_t freq;
7128 v_CONTEXT_t pVosContext = NULL;
7129 ptSapContext pSapCtx = NULL;
7130
7131 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7132 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7133 return -EINVAL;
7134 }
7135
7136 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7137 qca_wlan_vendor_attr_policy)) {
7138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7139 return -EINVAL;
7140 }
7141
7142 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7143 hddLog(VOS_TRACE_LEVEL_ERROR,
7144 FL("Attribute peerMac not provided for mode=%d"),
7145 adapter->device_mode);
7146 return -EINVAL;
7147 }
7148
7149 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7150 sizeof(peer_mac));
7151 hddLog(VOS_TRACE_LEVEL_INFO,
7152 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7153 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7154
7155 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7156 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7157 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7158 if ((hdd_sta_ctx->conn_info.connState !=
7159 eConnectionState_Associated) ||
7160 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7161 VOS_MAC_ADDRESS_LEN)) {
7162 hddLog(VOS_TRACE_LEVEL_ERROR,
7163 FL("Not Associated to mac "MAC_ADDRESS_STR),
7164 MAC_ADDR_ARRAY(peer_mac));
7165 return -EINVAL;
7166 }
7167
7168 nss = 1; //pronto supports only one spatial stream
7169 freq = vos_chan_to_freq(
7170 hdd_sta_ctx->conn_info.operationChannel);
7171 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7172
7173 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7174 adapter->device_mode == WLAN_HDD_SOFTAP) {
7175
7176 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7177 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7178 if(pSapCtx == NULL){
7179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7180 FL("psapCtx is NULL"));
7181 return -ENOENT;
7182 }
7183
7184
7185 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7186 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7187 !vos_is_macaddr_broadcast(
7188 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7189 vos_mem_compare(
7190 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7191 peer_mac, VOS_MAC_ADDRESS_LEN))
7192 break;
7193 }
7194
7195 if (WLAN_MAX_STA_COUNT == sta_id) {
7196 hddLog(VOS_TRACE_LEVEL_ERROR,
7197 FL("No active peer with mac="MAC_ADDRESS_STR),
7198 MAC_ADDR_ARRAY(peer_mac));
7199 return -EINVAL;
7200 }
7201
7202 nss = 1; //pronto supports only one spatial stream
7203 freq = vos_chan_to_freq(
7204 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7205 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7206 } else {
7207 hddLog(VOS_TRACE_LEVEL_ERROR,
7208 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7209 MAC_ADDR_ARRAY(peer_mac));
7210 return -EINVAL;
7211 }
7212
7213 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7214 if (rate_flags & eHAL_TX_RATE_VHT80) {
7215 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7216 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7217 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7218 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7219 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7220 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7221 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7222 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7223 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7224 if (rate_flags & eHAL_TX_RATE_HT40)
7225 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7226 }
7227
7228 if (rate_flags & eHAL_TX_RATE_SGI) {
7229 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7230 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7231 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7232 }
7233 }
7234
7235 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7236 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7237
7238 if (NULL == reply_skb) {
7239 hddLog(VOS_TRACE_LEVEL_ERROR,
7240 FL("getLinkProperties: skb alloc failed"));
7241 return -EINVAL;
7242 }
7243
7244 if (nla_put_u8(reply_skb,
7245 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7246 nss) ||
7247 nla_put_u8(reply_skb,
7248 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7249 final_rate_flags) ||
7250 nla_put_u32(reply_skb,
7251 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7252 freq)) {
7253 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7254 kfree_skb(reply_skb);
7255 return -EINVAL;
7256 }
7257
7258 return cfg80211_vendor_cmd_reply(reply_skb);
7259}
7260
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307261#define BEACON_MISS_THRESH_2_4 \
7262 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7263#define BEACON_MISS_THRESH_5_0 \
7264 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307265#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7266#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7267#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7268#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307269#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7270 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307271
7272/**
7273 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7274 * vendor command
7275 *
7276 * @wiphy: wiphy device pointer
7277 * @wdev: wireless device pointer
7278 * @data: Vendor command data buffer
7279 * @data_len: Buffer length
7280 *
7281 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7282 *
7283 * Return: EOK or other error codes.
7284 */
7285
7286static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7287 struct wireless_dev *wdev,
7288 const void *data,
7289 int data_len)
7290{
7291 struct net_device *dev = wdev->netdev;
7292 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7293 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7294 hdd_station_ctx_t *pHddStaCtx;
7295 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7296 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307297 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307298 eHalStatus status;
7299 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307300 uint8_t hb_thresh_val;
7301
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307302 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7303 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7304 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307305 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7306 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7307 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307308 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7309 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307310 };
7311
7312 ENTER();
7313
7314 if (VOS_FTM_MODE == hdd_get_conparam()) {
7315 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7316 return -EINVAL;
7317 }
7318
7319 ret_val = wlan_hdd_validate_context(pHddCtx);
7320 if (ret_val) {
7321 return ret_val;
7322 }
7323
7324 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7325
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307326 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7327 hddLog(LOGE, FL("Invalid ATTR"));
7328 return -EINVAL;
7329 }
7330
7331 /* check the Wifi Capability */
7332 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7333 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7334 {
7335 hddLog(VOS_TRACE_LEVEL_ERROR,
7336 FL("WIFICONFIG not supported by Firmware"));
7337 return -EINVAL;
7338 }
7339
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307340 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7341 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7342 modifyRoamParamsReq.value =
7343 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7344
7345 if (eHAL_STATUS_SUCCESS !=
7346 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7347 {
7348 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7349 ret_val = -EINVAL;
7350 }
7351 return ret_val;
7352 }
7353
7354 /* Moved this down in order to provide provision to set beacon
7355 * miss penalty count irrespective of connection state.
7356 */
7357 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7358 hddLog(LOGE, FL("Not in Connected state!"));
7359 return -ENOTSUPP;
7360 }
7361
7362 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307363
7364 if (!pReq) {
7365 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7366 "%s: Not able to allocate memory for tSetWifiConfigParams",
7367 __func__);
7368 return eHAL_STATUS_E_MALLOC_FAILED;
7369 }
7370
7371 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7372
7373 pReq->sessionId = pAdapter->sessionId;
7374 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7375
7376 if (tb[PARAM_MODULATED_DTIM]) {
7377 pReq->paramValue = nla_get_u32(
7378 tb[PARAM_MODULATED_DTIM]);
7379 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7380 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307381 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307382 hdd_set_pwrparams(pHddCtx);
7383 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7384 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7385
7386 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7387 iw_full_power_cbfn, pAdapter,
7388 eSME_FULL_PWR_NEEDED_BY_HDD);
7389 }
7390 else
7391 {
7392 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7393 }
7394 }
7395
7396 if (tb[PARAM_STATS_AVG_FACTOR]) {
7397 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7398 pReq->paramValue = nla_get_u16(
7399 tb[PARAM_STATS_AVG_FACTOR]);
7400 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7401 pReq->paramType, pReq->paramValue);
7402 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7403
7404 if (eHAL_STATUS_SUCCESS != status)
7405 {
7406 vos_mem_free(pReq);
7407 pReq = NULL;
7408 ret_val = -EPERM;
7409 return ret_val;
7410 }
7411 }
7412
7413
7414 if (tb[PARAM_GUARD_TIME]) {
7415 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7416 pReq->paramValue = nla_get_u32(
7417 tb[PARAM_GUARD_TIME]);
7418 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7419 pReq->paramType, pReq->paramValue);
7420 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7421
7422 if (eHAL_STATUS_SUCCESS != status)
7423 {
7424 vos_mem_free(pReq);
7425 pReq = NULL;
7426 ret_val = -EPERM;
7427 return ret_val;
7428 }
7429
7430 }
7431
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307432 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7433 hb_thresh_val = nla_get_u8(
7434 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7435
7436 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7437 hb_thresh_val);
7438 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7439 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7440 NULL, eANI_BOOLEAN_FALSE);
7441
7442 status = sme_update_hb_threshold(
7443 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7444 WNI_CFG_HEART_BEAT_THRESHOLD,
7445 hb_thresh_val, eCSR_BAND_24);
7446 if (eHAL_STATUS_SUCCESS != status) {
7447 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7448 vos_mem_free(pReq);
7449 pReq = NULL;
7450 return -EPERM;
7451 }
7452 }
7453
7454 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7455 hb_thresh_val = nla_get_u8(
7456 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7457
7458 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
7459 hb_thresh_val);
7460 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7461 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7462 NULL, eANI_BOOLEAN_FALSE);
7463
7464 status = sme_update_hb_threshold(
7465 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7466 WNI_CFG_HEART_BEAT_THRESHOLD,
7467 hb_thresh_val, eCSR_BAND_5G);
7468 if (eHAL_STATUS_SUCCESS != status) {
7469 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7470 vos_mem_free(pReq);
7471 pReq = NULL;
7472 return -EPERM;
7473 }
7474 }
7475
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307476 EXIT();
7477 return ret_val;
7478}
7479
7480/**
7481 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7482 * vendor command
7483 *
7484 * @wiphy: wiphy device pointer
7485 * @wdev: wireless device pointer
7486 * @data: Vendor command data buffer
7487 * @data_len: Buffer length
7488 *
7489 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7490 *
7491 * Return: EOK or other error codes.
7492 */
7493static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7494 struct wireless_dev *wdev,
7495 const void *data,
7496 int data_len)
7497{
7498 int ret;
7499
7500 vos_ssr_protect(__func__);
7501 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7502 data, data_len);
7503 vos_ssr_unprotect(__func__);
7504
7505 return ret;
7506}
Kapil Guptaee33bf12016-12-20 18:27:37 +05307507#ifdef WLAN_FEATURE_APFIND
7508/**
7509 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7510 * @wiphy: pointer to wireless wiphy structure.
7511 * @wdev: pointer to wireless_dev structure.
7512 * @data: pointer to apfind configuration data.
7513 * @data_len: the length in byte of apfind data.
7514 *
7515 * This is called when wlan driver needs to send APFIND configurations to
7516 * firmware.
7517 *
7518 * Return: An error code or 0 on success.
7519 */
7520static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7521 struct wireless_dev *wdev,
7522 const void *data, int data_len)
7523{
7524 struct sme_ap_find_request_req apfind_req;
7525 VOS_STATUS status;
7526 int ret_val;
7527 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7528
7529 ENTER();
7530
7531 ret_val = wlan_hdd_validate_context(hdd_ctx);
7532 if (ret_val)
7533 return ret_val;
7534
7535 if (VOS_FTM_MODE == hdd_get_conparam()) {
7536 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7537 return -EPERM;
7538 }
7539
7540 apfind_req.request_data_len = data_len;
7541 apfind_req.request_data = data;
7542
7543 status = sme_apfind_set_cmd(&apfind_req);
7544 if (VOS_STATUS_SUCCESS != status) {
7545 ret_val = -EIO;
7546 }
7547 return ret_val;
7548}
7549
7550/**
7551 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7552 * @wiphy: pointer to wireless wiphy structure.
7553 * @wdev: pointer to wireless_dev structure.
7554 * @data: pointer to apfind configuration data.
7555 * @data_len: the length in byte of apfind data.
7556 *
7557 * This is called when wlan driver needs to send APFIND configurations to
7558 * firmware.
7559 *
7560 * Return: An error code or 0 on success.
7561 */
7562static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7563 struct wireless_dev *wdev,
7564 const void *data, int data_len)
7565{
7566 int ret;
7567
7568 vos_ssr_protect(__func__);
7569 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
7570 vos_ssr_unprotect(__func__);
7571
7572 return ret;
7573}
7574#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307575const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7576{
Mukul Sharma2a271632014-10-13 14:59:01 +05307577 {
7578 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7579 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7580 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7581 WIPHY_VENDOR_CMD_NEED_NETDEV |
7582 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307583 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307584 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307585
7586 {
7587 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7588 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7589 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7590 WIPHY_VENDOR_CMD_NEED_NETDEV |
7591 WIPHY_VENDOR_CMD_NEED_RUNNING,
7592 .doit = wlan_hdd_cfg80211_nan_request
7593 },
7594
Sunil Duttc69bccb2014-05-26 21:30:20 +05307595#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7596 {
7597 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7598 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7599 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7600 WIPHY_VENDOR_CMD_NEED_NETDEV |
7601 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307602 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307603 },
7604
7605 {
7606 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7607 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7608 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7609 WIPHY_VENDOR_CMD_NEED_NETDEV |
7610 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307611 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307612 },
7613
7614 {
7615 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7616 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7617 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7618 WIPHY_VENDOR_CMD_NEED_NETDEV |
7619 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307620 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307621 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307622#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307623#ifdef WLAN_FEATURE_EXTSCAN
7624 {
7625 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7626 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7627 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7628 WIPHY_VENDOR_CMD_NEED_NETDEV |
7629 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307630 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307631 },
7632 {
7633 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7634 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7635 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7636 WIPHY_VENDOR_CMD_NEED_NETDEV |
7637 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307638 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307639 },
7640 {
7641 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7642 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7643 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7644 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307645 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05307646 },
7647 {
7648 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7649 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
7650 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7651 WIPHY_VENDOR_CMD_NEED_NETDEV |
7652 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307653 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05307654 },
7655 {
7656 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7657 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
7658 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7659 WIPHY_VENDOR_CMD_NEED_NETDEV |
7660 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307661 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05307662 },
7663 {
7664 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7665 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
7666 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7667 WIPHY_VENDOR_CMD_NEED_NETDEV |
7668 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307669 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307670 },
7671 {
7672 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7673 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
7674 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7675 WIPHY_VENDOR_CMD_NEED_NETDEV |
7676 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307677 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307678 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307679 {
7680 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7681 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
7682 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7683 WIPHY_VENDOR_CMD_NEED_NETDEV |
7684 WIPHY_VENDOR_CMD_NEED_RUNNING,
7685 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
7686 },
7687 {
7688 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7689 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
7690 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7691 WIPHY_VENDOR_CMD_NEED_NETDEV |
7692 WIPHY_VENDOR_CMD_NEED_RUNNING,
7693 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
7694 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307695#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307696/*EXT TDLS*/
7697 {
7698 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7699 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
7700 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7701 WIPHY_VENDOR_CMD_NEED_NETDEV |
7702 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307703 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05307704 },
7705 {
7706 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7707 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
7708 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7709 WIPHY_VENDOR_CMD_NEED_NETDEV |
7710 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307711 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05307712 },
7713 {
7714 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7715 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
7716 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7717 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307718 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05307719 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05307720 {
7721 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7722 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
7723 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7724 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307725 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05307726 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05307727 {
7728 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7729 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
7730 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7731 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307732 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05307733 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307734 {
7735 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7736 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
7737 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7738 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307739 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307740 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307741 {
7742 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7743 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
7744 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7745 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307746 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307747 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307748 {
7749 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05307750 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
7751 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7752 WIPHY_VENDOR_CMD_NEED_NETDEV |
7753 WIPHY_VENDOR_CMD_NEED_RUNNING,
7754 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
7755 },
7756 {
7757 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307758 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
7759 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7760 WIPHY_VENDOR_CMD_NEED_NETDEV |
7761 WIPHY_VENDOR_CMD_NEED_RUNNING,
7762 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05307763 },
7764 {
7765 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7766 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
7767 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7768 WIPHY_VENDOR_CMD_NEED_NETDEV,
7769 .doit = wlan_hdd_cfg80211_wifi_logger_start
7770 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05307771 {
7772 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7773 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
7774 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7775 WIPHY_VENDOR_CMD_NEED_NETDEV|
7776 WIPHY_VENDOR_CMD_NEED_RUNNING,
7777 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05307778 },
7779 {
7780 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7781 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
7782 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7783 WIPHY_VENDOR_CMD_NEED_NETDEV |
7784 WIPHY_VENDOR_CMD_NEED_RUNNING,
7785 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307786 },
7787 {
7788 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7789 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
7790 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7791 WIPHY_VENDOR_CMD_NEED_NETDEV |
7792 WIPHY_VENDOR_CMD_NEED_RUNNING,
7793 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307794 },
7795#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7796 {
7797 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7798 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
7799 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7800 WIPHY_VENDOR_CMD_NEED_NETDEV |
7801 WIPHY_VENDOR_CMD_NEED_RUNNING,
7802 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307803 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307804#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307805 {
7806 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7807 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
7808 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7809 WIPHY_VENDOR_CMD_NEED_NETDEV |
7810 WIPHY_VENDOR_CMD_NEED_RUNNING,
7811 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307812 },
7813 {
7814 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7815 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
7816 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7817 WIPHY_VENDOR_CMD_NEED_NETDEV |
7818 WIPHY_VENDOR_CMD_NEED_RUNNING,
7819 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05307820 },
7821#ifdef WLAN_FEATURE_APFIND
7822 {
7823 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7824 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
7825 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7826 WIPHY_VENDOR_CMD_NEED_NETDEV,
7827 .doit = wlan_hdd_cfg80211_apfind_cmd
7828 },
7829#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307830};
7831
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007832/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307833static const
7834struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007835{
7836#ifdef FEATURE_WLAN_CH_AVOID
7837 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05307838 .vendor_id = QCA_NL80211_VENDOR_ID,
7839 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007840 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307841#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
7842#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7843 {
7844 /* Index = 1*/
7845 .vendor_id = QCA_NL80211_VENDOR_ID,
7846 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
7847 },
7848 {
7849 /* Index = 2*/
7850 .vendor_id = QCA_NL80211_VENDOR_ID,
7851 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
7852 },
7853 {
7854 /* Index = 3*/
7855 .vendor_id = QCA_NL80211_VENDOR_ID,
7856 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
7857 },
7858 {
7859 /* Index = 4*/
7860 .vendor_id = QCA_NL80211_VENDOR_ID,
7861 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
7862 },
7863 {
7864 /* Index = 5*/
7865 .vendor_id = QCA_NL80211_VENDOR_ID,
7866 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
7867 },
7868 {
7869 /* Index = 6*/
7870 .vendor_id = QCA_NL80211_VENDOR_ID,
7871 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
7872 },
7873#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307874#ifdef WLAN_FEATURE_EXTSCAN
7875 {
7876 .vendor_id = QCA_NL80211_VENDOR_ID,
7877 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
7878 },
7879 {
7880 .vendor_id = QCA_NL80211_VENDOR_ID,
7881 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
7882 },
7883 {
7884 .vendor_id = QCA_NL80211_VENDOR_ID,
7885 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
7886 },
7887 {
7888 .vendor_id = QCA_NL80211_VENDOR_ID,
7889 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
7890 },
7891 {
7892 .vendor_id = QCA_NL80211_VENDOR_ID,
7893 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
7894 },
7895 {
7896 .vendor_id = QCA_NL80211_VENDOR_ID,
7897 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
7898 },
7899 {
7900 .vendor_id = QCA_NL80211_VENDOR_ID,
7901 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
7902 },
7903 {
7904 .vendor_id = QCA_NL80211_VENDOR_ID,
7905 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
7906 },
7907 {
7908 .vendor_id = QCA_NL80211_VENDOR_ID,
7909 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
7910 },
7911 {
7912 .vendor_id = QCA_NL80211_VENDOR_ID,
7913 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
7914 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307915 {
7916 .vendor_id = QCA_NL80211_VENDOR_ID,
7917 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
7918 },
7919 {
7920 .vendor_id = QCA_NL80211_VENDOR_ID,
7921 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
7922 },
7923 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
7924 .vendor_id = QCA_NL80211_VENDOR_ID,
7925 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
7926 },
7927 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
7928 .vendor_id = QCA_NL80211_VENDOR_ID,
7929 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
7930 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307931#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307932/*EXT TDLS*/
7933 {
7934 .vendor_id = QCA_NL80211_VENDOR_ID,
7935 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
7936 },
c_manjeecfd1efb2015-09-25 19:32:34 +05307937 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
7938 .vendor_id = QCA_NL80211_VENDOR_ID,
7939 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
7940 },
7941
Srinivas Dasari030bad32015-02-18 23:23:54 +05307942
7943 {
7944 .vendor_id = QCA_NL80211_VENDOR_ID,
7945 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
7946 },
7947
Sushant Kaushik084f6592015-09-10 13:11:56 +05307948 {
7949 .vendor_id = QCA_NL80211_VENDOR_ID,
7950 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307951 },
7952 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
7953 .vendor_id = QCA_NL80211_VENDOR_ID,
7954 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
7955 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05307956 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
7957 .vendor_id = QCA_NL80211_VENDOR_ID,
7958 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
7959 },
Sushant Kaushik084f6592015-09-10 13:11:56 +05307960
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007961};
7962
Jeff Johnson295189b2012-06-20 16:38:30 -07007963/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307964 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307965 * This function is called by hdd_wlan_startup()
7966 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307967 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07007968 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307969struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07007970{
7971 struct wiphy *wiphy;
7972 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307973 /*
7974 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07007975 */
7976 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
7977
7978 if (!wiphy)
7979 {
7980 /* Print error and jump into err label and free the memory */
7981 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
7982 return NULL;
7983 }
7984
Sunil Duttc69bccb2014-05-26 21:30:20 +05307985
Jeff Johnson295189b2012-06-20 16:38:30 -07007986 return wiphy;
7987}
7988
Anurag Chouhan343af7e2016-12-16 13:11:19 +05307989#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
7990 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
7991/**
7992 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
7993 * @wiphy: pointer to wiphy
7994 * @config: pointer to config
7995 *
7996 * Return: None
7997 */
7998static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
7999 hdd_config_t *config)
8000{
8001 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8002 if (config->max_sched_scan_plan_interval)
8003 wiphy->max_sched_scan_plan_interval =
8004 config->max_sched_scan_plan_interval;
8005 if (config->max_sched_scan_plan_iterations)
8006 wiphy->max_sched_scan_plan_iterations =
8007 config->max_sched_scan_plan_iterations;
8008}
8009#else
8010static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8011 hdd_config_t *config)
8012{
8013}
8014#endif
8015
Jeff Johnson295189b2012-06-20 16:38:30 -07008016/*
8017 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308018 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008019 * private ioctl to change the band value
8020 */
8021int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8022{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308023 int i, j;
8024 eNVChannelEnabledType channelEnabledState;
8025
Jeff Johnsone7245742012-09-05 17:12:55 -07008026 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308027
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308028 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008029 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308030
8031 if (NULL == wiphy->bands[i])
8032 {
8033 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8034 __func__, i);
8035 continue;
8036 }
8037
8038 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8039 {
8040 struct ieee80211_supported_band *band = wiphy->bands[i];
8041
8042 channelEnabledState = vos_nv_getChannelEnabledState(
8043 band->channels[j].hw_value);
8044
8045 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
8046 {
Abhishek Singh678227a2014-11-04 10:52:38 +05308047 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308048 continue;
8049 }
8050 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
8051 {
8052 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8053 continue;
8054 }
8055
8056 if (NV_CHANNEL_DISABLE == channelEnabledState ||
8057 NV_CHANNEL_INVALID == channelEnabledState)
8058 {
8059 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8060 }
8061 else if (NV_CHANNEL_DFS == channelEnabledState)
8062 {
8063 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8064 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
8065 }
8066 else
8067 {
8068 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
8069 |IEEE80211_CHAN_RADAR);
8070 }
8071 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008072 }
8073 return 0;
8074}
8075/*
8076 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308077 * This function is called by hdd_wlan_startup()
8078 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008079 * This function is used to initialize and register wiphy structure.
8080 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308081int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008082 struct wiphy *wiphy,
8083 hdd_config_t *pCfg
8084 )
8085{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308086 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308087 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8088
Jeff Johnsone7245742012-09-05 17:12:55 -07008089 ENTER();
8090
Jeff Johnson295189b2012-06-20 16:38:30 -07008091 /* Now bind the underlying wlan device with wiphy */
8092 set_wiphy_dev(wiphy, dev);
8093
8094 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008095
Kiet Lam6c583332013-10-14 05:37:09 +05308096#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008097 /* the flag for the other case would be initialzed in
8098 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05308099#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8100 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
8101#else
Amar Singhal0a402232013-10-11 20:57:16 -07008102 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05308103#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05308104#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008105
Amar Singhalfddc28c2013-09-05 13:03:40 -07008106 /* This will disable updating of NL channels from passive to
8107 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308108#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8109 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
8110#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07008111 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308112#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07008113
Amar Singhala49cbc52013-10-08 18:37:44 -07008114
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008115#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008116 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
8117 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
8118 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07008119 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308120#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05308121 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308122#else
8123 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
8124#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008125#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008126
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008127#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008128 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08008129#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008130 || pCfg->isFastRoamIniFeatureEnabled
8131#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008132#ifdef FEATURE_WLAN_ESE
8133 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008134#endif
8135 )
8136 {
8137 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
8138 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08008139#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008140#ifdef FEATURE_WLAN_TDLS
8141 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
8142 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
8143#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308144#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05308145 if (pCfg->configPNOScanSupport)
8146 {
8147 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
8148 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
8149 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
8150 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
8151 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308152#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008153
Abhishek Singh10d85972015-04-17 10:27:23 +05308154#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8155 wiphy->features |= NL80211_FEATURE_HT_IBSS;
8156#endif
8157
Amar Singhalfddc28c2013-09-05 13:03:40 -07008158#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008159 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
8160 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07008161 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008162 driver need to determine what to do with both
8163 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07008164
8165 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07008166#else
8167 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008168#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008169
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308170 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8171
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308172 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008173
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308174 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8175
Jeff Johnson295189b2012-06-20 16:38:30 -07008176 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308177 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8178 | BIT(NL80211_IFTYPE_ADHOC)
8179 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8180 | BIT(NL80211_IFTYPE_P2P_GO)
8181 | BIT(NL80211_IFTYPE_AP);
8182
8183 if (VOS_MONITOR_MODE == hdd_get_conparam())
8184 {
8185 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
8186 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008187
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308188 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008189 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308190#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8191 if( pCfg->enableMCC )
8192 {
8193 /* Currently, supports up to two channels */
8194 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008195
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308196 if( !pCfg->allowMCCGODiffBI )
8197 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008198
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308199 }
8200 wiphy->iface_combinations = &wlan_hdd_iface_combination;
8201 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008202#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308203 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008204
Jeff Johnson295189b2012-06-20 16:38:30 -07008205 /* Before registering we need to update the ht capabilitied based
8206 * on ini values*/
8207 if( !pCfg->ShortGI20MhzEnable )
8208 {
8209 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8210 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008211 }
8212
8213 if( !pCfg->ShortGI40MhzEnable )
8214 {
8215 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8216 }
8217
8218 if( !pCfg->nChannelBondingMode5GHz )
8219 {
8220 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8221 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308222 /*
8223 * In case of static linked driver at the time of driver unload,
8224 * module exit doesn't happens. Module cleanup helps in cleaning
8225 * of static memory.
8226 * If driver load happens statically, at the time of driver unload,
8227 * wiphy flags don't get reset because of static memory.
8228 * It's better not to store channel in static memory.
8229 */
8230 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8231 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8232 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8233 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8234 {
8235 hddLog(VOS_TRACE_LEVEL_ERROR,
8236 FL("Not enough memory to allocate channels"));
8237 return -ENOMEM;
8238 }
8239 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8240 &hdd_channels_2_4_GHZ[0],
8241 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008242
Agrawal Ashish97dec502015-11-26 20:20:58 +05308243 if (true == hdd_is_5g_supported(pHddCtx))
8244 {
8245 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8246 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8247 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8248 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8249 {
8250 hddLog(VOS_TRACE_LEVEL_ERROR,
8251 FL("Not enough memory to allocate channels"));
8252 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8253 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8254 return -ENOMEM;
8255 }
8256 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8257 &hdd_channels_5_GHZ[0],
8258 sizeof(hdd_channels_5_GHZ));
8259 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308260
8261 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8262 {
8263
8264 if (NULL == wiphy->bands[i])
8265 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308266 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308267 __func__, i);
8268 continue;
8269 }
8270
8271 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8272 {
8273 struct ieee80211_supported_band *band = wiphy->bands[i];
8274
8275 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8276 {
8277 // Enable social channels for P2P
8278 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8279 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8280 else
8281 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8282 continue;
8283 }
8284 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8285 {
8286 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8287 continue;
8288 }
8289 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008290 }
8291 /*Initialise the supported cipher suite details*/
8292 wiphy->cipher_suites = hdd_cipher_suites;
8293 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8294
8295 /*signal strength in mBm (100*dBm) */
8296 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8297
8298#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308299 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008300#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008301
Sunil Duttc69bccb2014-05-26 21:30:20 +05308302 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8303 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008304 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8305 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8306
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308307 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
8308
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308309 EXIT();
8310 return 0;
8311}
8312
8313/* In this function we are registering wiphy. */
8314int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8315{
8316 ENTER();
8317 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008318 if (0 > wiphy_register(wiphy))
8319 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308320 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008321 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8322 return -EIO;
8323 }
8324
8325 EXIT();
8326 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308327}
Jeff Johnson295189b2012-06-20 16:38:30 -07008328
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308329/* In this function we are updating channel list when,
8330 regulatory domain is FCC and country code is US.
8331 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8332 As per FCC smart phone is not a indoor device.
8333 GO should not opeate on indoor channels */
8334void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8335{
8336 int j;
8337 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8338 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8339 //Default counrtycode from NV at the time of wiphy initialization.
8340 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8341 &defaultCountryCode[0]))
8342 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008343 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308344 }
8345 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8346 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308347 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8348 {
8349 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8350 return;
8351 }
8352 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8353 {
8354 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8355 // Mark UNII -1 band channel as passive
8356 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8357 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8358 }
8359 }
8360}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308361/* This function registers for all frame which supplicant is interested in */
8362void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008363{
Jeff Johnson295189b2012-06-20 16:38:30 -07008364 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8365 /* Register for all P2P action, public action etc frames */
8366 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008367 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308368 /* Register frame indication call back */
8369 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008370 /* Right now we are registering these frame when driver is getting
8371 initialized. Once we will move to 2.6.37 kernel, in which we have
8372 frame register ops, we will move this code as a part of that */
8373 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308374 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008375 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8376
8377 /* GAS Initial Response */
8378 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8379 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308380
Jeff Johnson295189b2012-06-20 16:38:30 -07008381 /* GAS Comeback Request */
8382 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8383 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8384
8385 /* GAS Comeback Response */
8386 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8387 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8388
8389 /* P2P Public Action */
8390 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308391 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008392 P2P_PUBLIC_ACTION_FRAME_SIZE );
8393
8394 /* P2P Action */
8395 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8396 (v_U8_t*)P2P_ACTION_FRAME,
8397 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008398
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308399 /* WNM BSS Transition Request frame */
8400 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8401 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8402 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008403
8404 /* WNM-Notification */
8405 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8406 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8407 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008408}
8409
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308410void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008411{
Jeff Johnson295189b2012-06-20 16:38:30 -07008412 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8413 /* Register for all P2P action, public action etc frames */
8414 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8415
Jeff Johnsone7245742012-09-05 17:12:55 -07008416 ENTER();
8417
Jeff Johnson295189b2012-06-20 16:38:30 -07008418 /* Right now we are registering these frame when driver is getting
8419 initialized. Once we will move to 2.6.37 kernel, in which we have
8420 frame register ops, we will move this code as a part of that */
8421 /* GAS Initial Request */
8422
8423 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8424 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8425
8426 /* GAS Initial Response */
8427 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8428 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308429
Jeff Johnson295189b2012-06-20 16:38:30 -07008430 /* GAS Comeback Request */
8431 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8432 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8433
8434 /* GAS Comeback Response */
8435 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8436 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8437
8438 /* P2P Public Action */
8439 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308440 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008441 P2P_PUBLIC_ACTION_FRAME_SIZE );
8442
8443 /* P2P Action */
8444 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8445 (v_U8_t*)P2P_ACTION_FRAME,
8446 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008447 /* WNM-Notification */
8448 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8449 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8450 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008451}
8452
8453#ifdef FEATURE_WLAN_WAPI
8454void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308455 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008456{
8457 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8458 tCsrRoamSetKey setKey;
8459 v_BOOL_t isConnected = TRUE;
8460 int status = 0;
8461 v_U32_t roamId= 0xFF;
8462 tANI_U8 *pKeyPtr = NULL;
8463 int n = 0;
8464
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308465 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8466 __func__, hdd_device_modetoString(pAdapter->device_mode),
8467 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008468
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308469 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008470 setKey.keyId = key_index; // Store Key ID
8471 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8472 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8473 setKey.paeRole = 0 ; // the PAE role
8474 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8475 {
8476 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8477 }
8478 else
8479 {
8480 isConnected = hdd_connIsConnected(pHddStaCtx);
8481 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8482 }
8483 setKey.keyLength = key_Len;
8484 pKeyPtr = setKey.Key;
8485 memcpy( pKeyPtr, key, key_Len);
8486
Arif Hussain6d2a3322013-11-17 19:50:10 -08008487 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008488 __func__, key_Len);
8489 for (n = 0 ; n < key_Len; n++)
8490 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8491 __func__,n,setKey.Key[n]);
8492
8493 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8494 if ( isConnected )
8495 {
8496 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8497 pAdapter->sessionId, &setKey, &roamId );
8498 }
8499 if ( status != 0 )
8500 {
8501 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8502 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8503 __LINE__, status );
8504 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8505 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308506 /* Need to clear any trace of key value in the memory.
8507 * Thus zero out the memory even though it is local
8508 * variable.
8509 */
8510 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008511}
8512#endif /* FEATURE_WLAN_WAPI*/
8513
8514#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308515int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008516 beacon_data_t **ppBeacon,
8517 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008518#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308519int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008520 beacon_data_t **ppBeacon,
8521 struct cfg80211_beacon_data *params,
8522 int dtim_period)
8523#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308524{
Jeff Johnson295189b2012-06-20 16:38:30 -07008525 int size;
8526 beacon_data_t *beacon = NULL;
8527 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05308528 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
8529 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07008530
Jeff Johnsone7245742012-09-05 17:12:55 -07008531 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008532 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308533 {
8534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8535 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008536 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308537 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008538
8539 old = pAdapter->sessionCtx.ap.beacon;
8540
8541 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308542 {
8543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8544 FL("session(%d) old and new heads points to NULL"),
8545 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008546 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308547 }
8548
8549 if (params->tail && !params->tail_len)
8550 {
8551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8552 FL("tail_len is zero but tail is not NULL"));
8553 return -EINVAL;
8554 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008555
Jeff Johnson295189b2012-06-20 16:38:30 -07008556#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8557 /* Kernel 3.0 is not updating dtim_period for set beacon */
8558 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308559 {
8560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8561 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008562 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308563 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008564#endif
8565
Kapil Gupta137ef892016-12-13 19:38:00 +05308566 if (params->head)
8567 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008568 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308569 head = params->head;
8570 } else
8571 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008572 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308573 head = old->head;
8574 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008575
Kapil Gupta137ef892016-12-13 19:38:00 +05308576 if (params->tail || !old)
8577 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008578 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308579 tail = params->tail;
8580 } else
8581 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008582 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308583 tail = old->tail;
8584 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008585
Kapil Gupta137ef892016-12-13 19:38:00 +05308586 if (params->proberesp_ies || !old)
8587 {
8588 proberesp_ies_len = params->proberesp_ies_len;
8589 proberesp_ies = params->proberesp_ies;
8590 } else
8591 {
8592 proberesp_ies_len = old->proberesp_ies_len;
8593 proberesp_ies = old->proberesp_ies;
8594 }
8595
8596 if (params->assocresp_ies || !old)
8597 {
8598 assocresp_ies_len = params->assocresp_ies_len;
8599 assocresp_ies = params->assocresp_ies;
8600 } else
8601 {
8602 assocresp_ies_len = old->assocresp_ies_len;
8603 assocresp_ies = old->assocresp_ies;
8604 }
8605
8606 size = sizeof(beacon_data_t) + head_len + tail_len +
8607 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07008608
8609 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008610 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308611 {
8612 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8613 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008614 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308615 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008616
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008617#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05308618 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07008619 beacon->dtim_period = params->dtim_period;
8620 else
8621 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008622#else
Kapil Gupta137ef892016-12-13 19:38:00 +05308623 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008624 beacon->dtim_period = dtim_period;
8625 else
8626 beacon->dtim_period = old->dtim_period;
8627#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308628
Jeff Johnson295189b2012-06-20 16:38:30 -07008629 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8630 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308631 beacon->proberesp_ies = beacon->tail + tail_len;
8632 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
8633
Jeff Johnson295189b2012-06-20 16:38:30 -07008634 beacon->head_len = head_len;
8635 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308636 beacon->proberesp_ies_len = proberesp_ies_len;
8637 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07008638
Kapil Gupta137ef892016-12-13 19:38:00 +05308639 memcpy(beacon->head, head, head_len);
8640 memcpy(beacon->tail, tail, tail_len);
8641 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
8642 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008643
8644 *ppBeacon = beacon;
8645
8646 kfree(old);
8647
8648 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008649}
Jeff Johnson295189b2012-06-20 16:38:30 -07008650
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308651v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
8652#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
8653 const v_U8_t *pIes,
8654#else
8655 v_U8_t *pIes,
8656#endif
8657 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008658{
8659 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308660 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07008661 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308662
Jeff Johnson295189b2012-06-20 16:38:30 -07008663 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308664 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008665 elem_id = ptr[0];
8666 elem_len = ptr[1];
8667 left -= 2;
8668 if(elem_len > left)
8669 {
8670 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008671 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008672 eid,elem_len,left);
8673 return NULL;
8674 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308675 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008676 {
8677 return ptr;
8678 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308679
Jeff Johnson295189b2012-06-20 16:38:30 -07008680 left -= elem_len;
8681 ptr += (elem_len + 2);
8682 }
8683 return NULL;
8684}
8685
Jeff Johnson295189b2012-06-20 16:38:30 -07008686/* Check if rate is 11g rate or not */
8687static int wlan_hdd_rate_is_11g(u8 rate)
8688{
Sanjay Devnani28322e22013-06-21 16:13:40 -07008689 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008690 u8 i;
8691 for (i = 0; i < 8; i++)
8692 {
8693 if(rate == gRateArray[i])
8694 return TRUE;
8695 }
8696 return FALSE;
8697}
8698
8699/* Check for 11g rate and set proper 11g only mode */
8700static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
8701 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
8702{
8703 u8 i, num_rates = pIe[0];
8704
8705 pIe += 1;
8706 for ( i = 0; i < num_rates; i++)
8707 {
8708 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
8709 {
8710 /* If rate set have 11g rate than change the mode to 11G */
8711 *pSapHw_mode = eSAP_DOT11_MODE_11g;
8712 if (pIe[i] & BASIC_RATE_MASK)
8713 {
8714 /* If we have 11g rate as basic rate, it means mode
8715 is 11g only mode.
8716 */
8717 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
8718 *pCheckRatesfor11g = FALSE;
8719 }
8720 }
8721 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
8722 {
8723 *require_ht = TRUE;
8724 }
8725 }
8726 return;
8727}
8728
8729static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
8730{
8731 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8732 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8733 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8734 u8 checkRatesfor11g = TRUE;
8735 u8 require_ht = FALSE;
8736 u8 *pIe=NULL;
8737
8738 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
8739
8740 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
8741 pBeacon->head_len, WLAN_EID_SUPP_RATES);
8742 if (pIe != NULL)
8743 {
8744 pIe += 1;
8745 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8746 &pConfig->SapHw_mode);
8747 }
8748
8749 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8750 WLAN_EID_EXT_SUPP_RATES);
8751 if (pIe != NULL)
8752 {
8753
8754 pIe += 1;
8755 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8756 &pConfig->SapHw_mode);
8757 }
8758
8759 if( pConfig->channel > 14 )
8760 {
8761 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
8762 }
8763
8764 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8765 WLAN_EID_HT_CAPABILITY);
8766
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308767 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008768 {
8769 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
8770 if(require_ht)
8771 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
8772 }
8773}
8774
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308775static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
8776 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
8777{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008778 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308779 v_U8_t *pIe = NULL;
8780 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8781
8782 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
8783 pBeacon->tail, pBeacon->tail_len);
8784
8785 if (pIe)
8786 {
8787 ielen = pIe[1] + 2;
8788 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8789 {
8790 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
8791 }
8792 else
8793 {
8794 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
8795 return -EINVAL;
8796 }
8797 *total_ielen += ielen;
8798 }
8799 return 0;
8800}
8801
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008802static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
8803 v_U8_t *genie, v_U8_t *total_ielen)
8804{
8805 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8806 int left = pBeacon->tail_len;
8807 v_U8_t *ptr = pBeacon->tail;
8808 v_U8_t elem_id, elem_len;
8809 v_U16_t ielen = 0;
8810
8811 if ( NULL == ptr || 0 == left )
8812 return;
8813
8814 while (left >= 2)
8815 {
8816 elem_id = ptr[0];
8817 elem_len = ptr[1];
8818 left -= 2;
8819 if (elem_len > left)
8820 {
8821 hddLog( VOS_TRACE_LEVEL_ERROR,
8822 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
8823 elem_id, elem_len, left);
8824 return;
8825 }
8826 if (IE_EID_VENDOR == elem_id)
8827 {
8828 /* skipping the VSIE's which we don't want to include or
8829 * it will be included by existing code
8830 */
8831 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
8832#ifdef WLAN_FEATURE_WFD
8833 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
8834#endif
8835 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8836 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8837 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
8838 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8839 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
8840 {
8841 ielen = ptr[1] + 2;
8842 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8843 {
8844 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
8845 *total_ielen += ielen;
8846 }
8847 else
8848 {
8849 hddLog( VOS_TRACE_LEVEL_ERROR,
8850 "IE Length is too big "
8851 "IEs eid=%d elem_len=%d total_ie_lent=%d",
8852 elem_id, elem_len, *total_ielen);
8853 }
8854 }
8855 }
8856
8857 left -= elem_len;
8858 ptr += (elem_len + 2);
8859 }
8860 return;
8861}
8862
Kapil Gupta137ef892016-12-13 19:38:00 +05308863int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008864{
8865 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308866 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008867 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07008868 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05308869 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008870
8871 genie = vos_mem_malloc(MAX_GENIE_LEN);
8872
8873 if(genie == NULL) {
8874
8875 return -ENOMEM;
8876 }
8877
Kapil Gupta137ef892016-12-13 19:38:00 +05308878 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308879 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8880 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008881 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308882 hddLog(LOGE,
8883 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308884 ret = -EINVAL;
8885 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008886 }
8887
8888#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308889 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8890 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
8891 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308892 hddLog(LOGE,
8893 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308894 ret = -EINVAL;
8895 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008896 }
8897#endif
8898
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308899 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8900 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008901 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308902 hddLog(LOGE,
8903 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308904 ret = -EINVAL;
8905 goto done;
8906 }
8907
8908 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
8909 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008910 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07008911 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008912
8913 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8914 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
8915 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
8916 {
8917 hddLog(LOGE,
8918 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008919 ret = -EINVAL;
8920 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008921 }
8922
8923 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8924 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
8925 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8926 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8927 ==eHAL_STATUS_FAILURE)
8928 {
8929 hddLog(LOGE,
8930 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008931 ret = -EINVAL;
8932 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008933 }
8934
8935 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05308936 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008937 {
Kapil Gupta137ef892016-12-13 19:38:00 +05308938 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07008939 u8 probe_rsp_ie_len[3] = {0};
8940 u8 counter = 0;
8941 /* Check Probe Resp Length if it is greater then 255 then Store
8942 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
8943 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
8944 Store More then 255 bytes into One Variable.
8945 */
8946 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
8947 {
8948 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
8949 {
8950 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
8951 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
8952 }
8953 else
8954 {
8955 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
8956 rem_probe_resp_ie_len = 0;
8957 }
8958 }
8959
8960 rem_probe_resp_ie_len = 0;
8961
8962 if (probe_rsp_ie_len[0] > 0)
8963 {
8964 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8965 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05308966 (tANI_U8*)&pBeacon->
8967 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07008968 probe_rsp_ie_len[0], NULL,
8969 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8970 {
8971 hddLog(LOGE,
8972 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008973 ret = -EINVAL;
8974 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008975 }
8976 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
8977 }
8978
8979 if (probe_rsp_ie_len[1] > 0)
8980 {
8981 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8982 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05308983 (tANI_U8*)&pBeacon->
8984 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07008985 probe_rsp_ie_len[1], NULL,
8986 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8987 {
8988 hddLog(LOGE,
8989 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008990 ret = -EINVAL;
8991 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008992 }
8993 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
8994 }
8995
8996 if (probe_rsp_ie_len[2] > 0)
8997 {
8998 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8999 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05309000 (tANI_U8*)&pBeacon->
9001 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009002 probe_rsp_ie_len[2], NULL,
9003 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9004 {
9005 hddLog(LOGE,
9006 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009007 ret = -EINVAL;
9008 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009009 }
9010 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9011 }
9012
9013 if (probe_rsp_ie_len[1] == 0 )
9014 {
9015 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9016 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9017 eANI_BOOLEAN_FALSE) )
9018 {
9019 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009020 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009021 }
9022 }
9023
9024 if (probe_rsp_ie_len[2] == 0 )
9025 {
9026 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9027 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9028 eANI_BOOLEAN_FALSE) )
9029 {
9030 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009031 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009032 }
9033 }
9034
9035 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9036 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9037 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9038 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9039 == eHAL_STATUS_FAILURE)
9040 {
9041 hddLog(LOGE,
9042 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009043 ret = -EINVAL;
9044 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009045 }
9046 }
9047 else
9048 {
9049 // Reset WNI_CFG_PROBE_RSP Flags
9050 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
9051
9052 hddLog(VOS_TRACE_LEVEL_INFO,
9053 "%s: No Probe Response IE received in set beacon",
9054 __func__);
9055 }
9056
9057 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309058 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009059 {
9060 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05309061 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
9062 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07009063 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9064 {
9065 hddLog(LOGE,
9066 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009067 ret = -EINVAL;
9068 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009069 }
9070
9071 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9072 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
9073 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9074 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9075 == eHAL_STATUS_FAILURE)
9076 {
9077 hddLog(LOGE,
9078 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009079 ret = -EINVAL;
9080 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009081 }
9082 }
9083 else
9084 {
9085 hddLog(VOS_TRACE_LEVEL_INFO,
9086 "%s: No Assoc Response IE received in set beacon",
9087 __func__);
9088
9089 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9090 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9091 eANI_BOOLEAN_FALSE) )
9092 {
9093 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009094 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009095 }
9096 }
9097
Jeff Johnsone7245742012-09-05 17:12:55 -07009098done:
Jeff Johnson295189b2012-06-20 16:38:30 -07009099 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309100 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009101}
Jeff Johnson295189b2012-06-20 16:38:30 -07009102
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309103/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009104 * FUNCTION: wlan_hdd_validate_operation_channel
9105 * called by wlan_hdd_cfg80211_start_bss() and
9106 * wlan_hdd_cfg80211_set_channel()
9107 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309108 * channel list.
9109 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07009110VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009111{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309112
Jeff Johnson295189b2012-06-20 16:38:30 -07009113 v_U32_t num_ch = 0;
9114 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
9115 u32 indx = 0;
9116 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309117 v_U8_t fValidChannel = FALSE, count = 0;
9118 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309119
Jeff Johnson295189b2012-06-20 16:38:30 -07009120 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9121
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309122 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009123 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309124 /* Validate the channel */
9125 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009126 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309127 if ( channel == rfChannels[count].channelNum )
9128 {
9129 fValidChannel = TRUE;
9130 break;
9131 }
9132 }
9133 if (fValidChannel != TRUE)
9134 {
9135 hddLog(VOS_TRACE_LEVEL_ERROR,
9136 "%s: Invalid Channel [%d]", __func__, channel);
9137 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009138 }
9139 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309140 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009141 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309142 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
9143 valid_ch, &num_ch))
9144 {
9145 hddLog(VOS_TRACE_LEVEL_ERROR,
9146 "%s: failed to get valid channel list", __func__);
9147 return VOS_STATUS_E_FAILURE;
9148 }
9149 for (indx = 0; indx < num_ch; indx++)
9150 {
9151 if (channel == valid_ch[indx])
9152 {
9153 break;
9154 }
9155 }
9156
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309157 if (indx >= num_ch)
9158 {
9159 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9160 {
9161 eCsrBand band;
9162 unsigned int freq;
9163
9164 sme_GetFreqBand(hHal, &band);
9165
9166 if (eCSR_BAND_5G == band)
9167 {
9168#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9169 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9170 {
9171 freq = ieee80211_channel_to_frequency(channel,
9172 IEEE80211_BAND_2GHZ);
9173 }
9174 else
9175 {
9176 freq = ieee80211_channel_to_frequency(channel,
9177 IEEE80211_BAND_5GHZ);
9178 }
9179#else
9180 freq = ieee80211_channel_to_frequency(channel);
9181#endif
9182 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
9183 return VOS_STATUS_SUCCESS;
9184 }
9185 }
9186
9187 hddLog(VOS_TRACE_LEVEL_ERROR,
9188 "%s: Invalid Channel [%d]", __func__, channel);
9189 return VOS_STATUS_E_FAILURE;
9190 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009191 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309192
Jeff Johnson295189b2012-06-20 16:38:30 -07009193 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309194
Jeff Johnson295189b2012-06-20 16:38:30 -07009195}
9196
Viral Modi3a32cc52013-02-08 11:14:52 -08009197/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309198 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009199 * This function is used to set the channel number
9200 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309201static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009202 struct ieee80211_channel *chan,
9203 enum nl80211_channel_type channel_type
9204 )
9205{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309206 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009207 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009208 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009209 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309210 hdd_context_t *pHddCtx;
9211 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009212
9213 ENTER();
9214
9215 if( NULL == dev )
9216 {
9217 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009218 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009219 return -ENODEV;
9220 }
9221 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309222
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309223 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9224 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
9225 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08009226 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309227 "%s: device_mode = %s (%d) freq = %d", __func__,
9228 hdd_device_modetoString(pAdapter->device_mode),
9229 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309230
9231 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9232 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309233 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08009234 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309235 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009236 }
9237
9238 /*
9239 * Do freq to chan conversion
9240 * TODO: for 11a
9241 */
9242
9243 channel = ieee80211_frequency_to_channel(freq);
9244
9245 /* Check freq range */
9246 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9247 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9248 {
9249 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009250 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009251 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9252 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9253 return -EINVAL;
9254 }
9255
9256 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9257
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309258 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9259 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009260 {
9261 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
9262 {
9263 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009264 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009265 return -EINVAL;
9266 }
9267 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9268 "%s: set channel to [%d] for device mode =%d",
9269 __func__, channel,pAdapter->device_mode);
9270 }
9271 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009272 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009273 )
9274 {
9275 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9276 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9277 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9278
9279 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9280 {
9281 /* Link is up then return cant set channel*/
9282 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009283 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009284 return -EINVAL;
9285 }
9286
9287 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9288 pHddStaCtx->conn_info.operationChannel = channel;
9289 pRoamProfile->ChannelInfo.ChannelList =
9290 &pHddStaCtx->conn_info.operationChannel;
9291 }
9292 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009293 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009294 )
9295 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309296 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9297 {
9298 if(VOS_STATUS_SUCCESS !=
9299 wlan_hdd_validate_operation_channel(pAdapter,channel))
9300 {
9301 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009302 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309303 return -EINVAL;
9304 }
9305 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9306 }
9307 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009308 {
9309 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9310
9311 /* If auto channel selection is configured as enable/ 1 then ignore
9312 channel set by supplicant
9313 */
9314 if ( cfg_param->apAutoChannelSelection )
9315 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309316 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9317 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009318 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309319 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9320 __func__, hdd_device_modetoString(pAdapter->device_mode),
9321 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009322 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309323 else
9324 {
9325 if(VOS_STATUS_SUCCESS !=
9326 wlan_hdd_validate_operation_channel(pAdapter,channel))
9327 {
9328 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009329 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309330 return -EINVAL;
9331 }
9332 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9333 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009334 }
9335 }
9336 else
9337 {
9338 hddLog(VOS_TRACE_LEVEL_FATAL,
9339 "%s: Invalid device mode failed to set valid channel", __func__);
9340 return -EINVAL;
9341 }
9342 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309343 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009344}
9345
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309346static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9347 struct net_device *dev,
9348 struct ieee80211_channel *chan,
9349 enum nl80211_channel_type channel_type
9350 )
9351{
9352 int ret;
9353
9354 vos_ssr_protect(__func__);
9355 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9356 vos_ssr_unprotect(__func__);
9357
9358 return ret;
9359}
9360
Anurag Chouhan83026002016-12-13 22:46:21 +05309361#ifdef DHCP_SERVER_OFFLOAD
9362void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
9363 VOS_STATUS status)
9364{
9365 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
9366
9367 ENTER();
9368
9369 if (NULL == adapter)
9370 {
9371 hddLog(VOS_TRACE_LEVEL_ERROR,
9372 "%s: adapter is NULL",__func__);
9373 return;
9374 }
9375
9376 adapter->dhcp_status.dhcp_offload_status = status;
9377 vos_event_set(&adapter->dhcp_status.vos_event);
9378 return;
9379}
9380
9381/**
9382 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
9383 * @hostapd_adapter: pointer to hostapd adapter.
9384 *
9385 * Return: None
9386 */
9387static VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter)
9388{
9389 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
9390 sir_dhcp_srv_offload_info dhcp_srv_info;
9391 tANI_U8 num_entries = 0;
9392 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
9393 tANI_U8 num;
9394 tANI_U32 temp;
9395 VOS_STATUS ret;
9396
9397 ENTER();
9398
9399 ret = wlan_hdd_validate_context(hdd_ctx);
9400 if (0 != ret)
9401 return VOS_STATUS_E_INVAL;
9402
9403 /* Prepare the request to send to SME */
9404 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
9405 if (NULL == dhcp_srv_info) {
9406 hddLog(VOS_TRACE_LEVEL_ERROR,
9407 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
9408 return VOS_STATUS_E_NOMEM;
9409 }
9410
9411 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
9412
9413 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
9414 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
9415 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
9416 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
9417 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
9418 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
9419
9420 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
9421 srv_ip,
9422 &num_entries,
Anurag Chouhanac145c22016-11-22 16:51:47 +05309423 IPADDR_NUM_ENTRIES, ".");
Anurag Chouhan83026002016-12-13 22:46:21 +05309424 if (num_entries != IPADDR_NUM_ENTRIES) {
9425 hddLog(VOS_TRACE_LEVEL_ERROR,
9426 "%s: incorrect IP address (%s) assigned for DHCP server!",
9427 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9428 vos_mem_free(dhcp_srv_info);
9429 return VOS_STATUS_E_FAILURE;
9430 }
9431
9432 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
9433 hddLog(VOS_TRACE_LEVEL_ERROR,
9434 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
9435 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9436 vos_mem_free(dhcp_srv_info);
9437 return VOS_STATUS_E_FAILURE;
9438 }
9439
9440 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
9441 hddLog(VOS_TRACE_LEVEL_ERROR,
9442 "%s: invalid IP address (%s)! The last field must be less than 100!",
9443 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9444 vos_mem_free(dhcp_srv_info);
9445 return VOS_STATUS_E_FAILURE;
9446 }
9447
9448 for (num = 0; num < num_entries; num++) {
9449 temp = srv_ip[num];
9450 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
9451 }
9452
9453 if (eHAL_STATUS_SUCCESS !=
9454 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
9455 hddLog(VOS_TRACE_LEVEL_ERROR,
9456 "%s: sme_set_dhcp_srv_offload fail!", __func__);
9457 vos_mem_free(dhcp_srv_info);
9458 return VOS_STATUS_E_FAILURE;
9459 }
9460
9461 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9462 "%s: enable DHCP Server offload successfully!", __func__);
9463
9464 vos_mem_free(dhcp_srv_info);
9465 return 0;
9466}
9467#endif /* DHCP_SERVER_OFFLOAD */
9468
Jeff Johnson295189b2012-06-20 16:38:30 -07009469#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9470static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9471 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009472#else
9473static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9474 struct cfg80211_beacon_data *params,
9475 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309476 enum nl80211_hidden_ssid hidden_ssid,
9477 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009478#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009479{
9480 tsap_Config_t *pConfig;
9481 beacon_data_t *pBeacon = NULL;
9482 struct ieee80211_mgmt *pMgmt_frame;
9483 v_U8_t *pIe=NULL;
9484 v_U16_t capab_info;
9485 eCsrAuthType RSNAuthType;
9486 eCsrEncryptionType RSNEncryptType;
9487 eCsrEncryptionType mcRSNEncryptType;
9488 int status = VOS_STATUS_SUCCESS;
9489 tpWLAN_SAPEventCB pSapEventCallback;
9490 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -07009491 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309492 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009493 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309494 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009495 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009496 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309497 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009498 v_BOOL_t MFPCapable = VOS_FALSE;
9499 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309500 v_BOOL_t sapEnable11AC =
9501 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +05309502 u_int16_t prev_rsn_length = 0;
9503
Jeff Johnson295189b2012-06-20 16:38:30 -07009504 ENTER();
9505
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309506 iniConfig = pHddCtx->cfg_ini;
9507
Jeff Johnson295189b2012-06-20 16:38:30 -07009508 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9509
9510 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9511
9512 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9513
9514 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9515
9516 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9517
9518 //channel is already set in the set_channel Call back
9519 //pConfig->channel = pCommitConfig->channel;
9520
9521 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309522 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009523 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9524
9525 pConfig->dtim_period = pBeacon->dtim_period;
9526
Arif Hussain6d2a3322013-11-17 19:50:10 -08009527 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009528 pConfig->dtim_period);
9529
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009530 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009531 {
9532 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009533 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309534 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9535 {
9536 tANI_BOOLEAN restartNeeded;
9537 pConfig->ieee80211d = 1;
9538 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9539 sme_setRegInfo(hHal, pConfig->countryCode);
9540 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9541 }
9542 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009543 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009544 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009545 pConfig->ieee80211d = 1;
9546 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9547 sme_setRegInfo(hHal, pConfig->countryCode);
9548 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009549 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009550 else
9551 {
9552 pConfig->ieee80211d = 0;
9553 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309554 /*
9555 * If auto channel is configured i.e. channel is 0,
9556 * so skip channel validation.
9557 */
9558 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9559 {
9560 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9561 {
9562 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009563 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309564 return -EINVAL;
9565 }
9566 }
9567 else
9568 {
9569 if(1 != pHddCtx->is_dynamic_channel_range_set)
9570 {
9571 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9572 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9573 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9574 }
9575 pHddCtx->is_dynamic_channel_range_set = 0;
9576 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009577 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009578 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009579 {
9580 pConfig->ieee80211d = 0;
9581 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309582
9583#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9584 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9585 pConfig->authType = eSAP_OPEN_SYSTEM;
9586 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9587 pConfig->authType = eSAP_SHARED_KEY;
9588 else
9589 pConfig->authType = eSAP_AUTO_SWITCH;
9590#else
9591 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9592 pConfig->authType = eSAP_OPEN_SYSTEM;
9593 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9594 pConfig->authType = eSAP_SHARED_KEY;
9595 else
9596 pConfig->authType = eSAP_AUTO_SWITCH;
9597#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009598
9599 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309600
9601 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009602 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +05309603#ifdef SAP_AUTH_OFFLOAD
9604 /* In case of sap offload, hostapd.conf is configuted with open mode and
9605 * security is configured from ini file. Due to open mode in hostapd.conf
9606 * privacy bit is set to false which will result in not sending,
9607 * data packets as encrypted.
9608 * If enable_sap_auth_offload is enabled in ini and
9609 * sap_auth_offload_sec_type is type of WPA2-PSK,
9610 * driver will set privacy bit to 1.
9611 */
9612 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
9613 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
9614 pConfig->privacy = VOS_TRUE;
9615#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009616
9617 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9618
9619 /*Set wps station to configured*/
9620 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9621
9622 if(pIe)
9623 {
9624 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9625 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009626 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009627 return -EINVAL;
9628 }
9629 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
9630 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009631 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07009632 /* Check 15 bit of WPS IE as it contain information for wps state
9633 * WPS state
9634 */
9635 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
9636 {
9637 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
9638 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
9639 {
9640 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
9641 }
9642 }
9643 }
9644 else
9645 {
9646 pConfig->wps_state = SAP_WPS_DISABLED;
9647 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309648 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07009649
c_hpothufe599e92014-06-16 11:38:55 +05309650 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9651 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9652 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
9653 eCSR_ENCRYPT_TYPE_NONE;
9654
Jeff Johnson295189b2012-06-20 16:38:30 -07009655 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309656 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309657 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009658 WLAN_EID_RSN);
9659 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309660 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009661 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +05309662 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
9663 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
9664 pConfig->RSNWPAReqIELength);
9665 else
9666 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
9667 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309668 /* The actual processing may eventually be more extensive than
9669 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07009670 * by the app.
9671 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309672 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009673 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9674 &RSNEncryptType,
9675 &mcRSNEncryptType,
9676 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009677 &MFPCapable,
9678 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +05309679 pConfig->RSNWPAReqIE[1]+2,
9680 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009681
9682 if( VOS_STATUS_SUCCESS == status )
9683 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309684 /* Now copy over all the security attributes you have
9685 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009686 * */
9687 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9688 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9689 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9690 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309691 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009692 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009693 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9694 }
9695 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309696
Jeff Johnson295189b2012-06-20 16:38:30 -07009697 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9698 pBeacon->tail, pBeacon->tail_len);
9699
9700 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
9701 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309702 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07009703 {
9704 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +05309705 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -07009706 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +05309707 if (pConfig->RSNWPAReqIELength <=
9708 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
9709 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
9710 pIe[1] + 2);
9711 else
9712 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
9713 pConfig->RSNWPAReqIELength);
9714
Jeff Johnson295189b2012-06-20 16:38:30 -07009715 }
9716 else
9717 {
9718 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +05309719 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
9720 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
9721 pConfig->RSNWPAReqIELength);
9722 else
9723 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
9724 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309725 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009726 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9727 &RSNEncryptType,
9728 &mcRSNEncryptType,
9729 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009730 &MFPCapable,
9731 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +05309732 pConfig->RSNWPAReqIE[1]+2,
9733 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009734
9735 if( VOS_STATUS_SUCCESS == status )
9736 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309737 /* Now copy over all the security attributes you have
9738 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009739 * */
9740 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9741 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9742 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9743 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309744 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009745 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009746 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9747 }
9748 }
9749 }
9750
Kapil Gupta137ef892016-12-13 19:38:00 +05309751 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -07009752 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
9753 return -EINVAL;
9754 }
9755
Jeff Johnson295189b2012-06-20 16:38:30 -07009756 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
9757
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009758#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009759 if (params->ssid != NULL)
9760 {
9761 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
9762 pConfig->SSIDinfo.ssid.length = params->ssid_len;
9763 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9764 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9765 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009766#else
9767 if (ssid != NULL)
9768 {
9769 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
9770 pConfig->SSIDinfo.ssid.length = ssid_len;
9771 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9772 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9773 }
9774#endif
9775
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309776 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07009777 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309778
Jeff Johnson295189b2012-06-20 16:38:30 -07009779 /* default value */
9780 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9781 pConfig->num_accept_mac = 0;
9782 pConfig->num_deny_mac = 0;
9783
9784 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9785 pBeacon->tail, pBeacon->tail_len);
9786
9787 /* pIe for black list is following form:
9788 type : 1 byte
9789 length : 1 byte
9790 OUI : 4 bytes
9791 acl type : 1 byte
9792 no of mac addr in black list: 1 byte
9793 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309794 */
9795 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009796 {
9797 pConfig->SapMacaddr_acl = pIe[6];
9798 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009799 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009800 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309801 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
9802 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009803 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9804 for (i = 0; i < pConfig->num_deny_mac; i++)
9805 {
9806 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9807 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309808 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009809 }
9810 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9811 pBeacon->tail, pBeacon->tail_len);
9812
9813 /* pIe for white list is following form:
9814 type : 1 byte
9815 length : 1 byte
9816 OUI : 4 bytes
9817 acl type : 1 byte
9818 no of mac addr in white list: 1 byte
9819 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309820 */
9821 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009822 {
9823 pConfig->SapMacaddr_acl = pIe[6];
9824 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009825 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009826 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309827 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
9828 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009829 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9830 for (i = 0; i < pConfig->num_accept_mac; i++)
9831 {
9832 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9833 acl_entry++;
9834 }
9835 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309836
Jeff Johnson295189b2012-06-20 16:38:30 -07009837 wlan_hdd_set_sapHwmode(pHostapdAdapter);
9838
Jeff Johnsone7245742012-09-05 17:12:55 -07009839#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009840 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309841 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
9842 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05309843 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
9844 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009845 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
9846 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309847 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
9848 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07009849 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309850 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07009851 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309852 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009853
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309854 /* If ACS disable and selected channel <= 14
9855 * OR
9856 * ACS enabled and ACS operating band is choosen as 2.4
9857 * AND
9858 * VHT in 2.4G Disabled
9859 * THEN
9860 * Fallback to 11N mode
9861 */
9862 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
9863 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05309864 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309865 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009866 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309867 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
9868 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009869 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
9870 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009871 }
9872#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309873
Jeff Johnson295189b2012-06-20 16:38:30 -07009874 // ht_capab is not what the name conveys,this is used for protection bitmap
9875 pConfig->ht_capab =
9876 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
9877
Kapil Gupta137ef892016-12-13 19:38:00 +05309878 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07009879 {
9880 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9881 return -EINVAL;
9882 }
9883
9884 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309885 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07009886 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
9887 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309888 pConfig->obssProtEnabled =
9889 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07009890
Chet Lanctot8cecea22014-02-11 19:09:36 -08009891#ifdef WLAN_FEATURE_11W
9892 pConfig->mfpCapable = MFPCapable;
9893 pConfig->mfpRequired = MFPRequired;
9894 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
9895 pConfig->mfpCapable, pConfig->mfpRequired);
9896#endif
9897
Arif Hussain6d2a3322013-11-17 19:50:10 -08009898 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07009899 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009900 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
9901 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
9902 (int)pConfig->channel);
9903 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
9904 pConfig->SapHw_mode, pConfig->privacy,
9905 pConfig->authType);
9906 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
9907 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
9908 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
9909 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07009910
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309911 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009912 {
9913 //Bss already started. just return.
9914 //TODO Probably it should update some beacon params.
9915 hddLog( LOGE, "Bss Already started...Ignore the request");
9916 EXIT();
9917 return 0;
9918 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309919
Agarwal Ashish51325b52014-06-16 16:50:49 +05309920 if (vos_max_concurrent_connections_reached()) {
9921 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9922 return -EINVAL;
9923 }
9924
Jeff Johnson295189b2012-06-20 16:38:30 -07009925 pConfig->persona = pHostapdAdapter->device_mode;
9926
Peng Xu2446a892014-09-05 17:21:18 +05309927 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
9928 if ( NULL != psmeConfig)
9929 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309930 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05309931 sme_GetConfigParam(hHal, psmeConfig);
9932 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309933#ifdef WLAN_FEATURE_AP_HT40_24G
9934 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
9935 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
9936 && pHddCtx->cfg_ini->apHT40_24GEnabled)
9937 {
9938 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
9939 sme_UpdateConfig (hHal, psmeConfig);
9940 }
9941#endif
Peng Xu2446a892014-09-05 17:21:18 +05309942 vos_mem_free(psmeConfig);
9943 }
Peng Xuafc34e32014-09-25 13:23:55 +05309944 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05309945
Jeff Johnson295189b2012-06-20 16:38:30 -07009946 pSapEventCallback = hdd_hostapd_SAPEventCB;
9947 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
9948 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
9949 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009950 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009951 return -EINVAL;
9952 }
9953
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309954 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07009955 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
9956
9957 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309958
Jeff Johnson295189b2012-06-20 16:38:30 -07009959 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309960 {
9961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009962 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07009963 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009964 VOS_ASSERT(0);
9965 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309966
Jeff Johnson295189b2012-06-20 16:38:30 -07009967 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +05309968 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
9969 VOS_STATUS_SUCCESS)
9970 {
9971 hddLog(LOGE,FL("Fail to get Softap sessionID"));
9972 VOS_ASSERT(0);
9973 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +05309974 /* Initialize WMM configuation */
9975 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309976 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009977
Anurag Chouhan83026002016-12-13 22:46:21 +05309978#ifdef DHCP_SERVER_OFFLOAD
9979 /* set dhcp server offload */
9980 if (iniConfig->enable_dhcp_srv_offload &&
9981 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
9982 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter);
9983 if (!VOS_IS_STATUS_SUCCESS(status))
9984 {
9985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9986 ("HDD DHCP Server Offload Failed!!"));
9987 return -EINVAL;
9988 }
9989 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
9990 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
9991 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
9992 {
9993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9994 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
9995 pHostapdAdapter->dhcp_status.dhcp_offload_status);
9996 return -EINVAL;
9997 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +05309998#ifdef MDNS_OFFLOAD
9999 if (iniConfig->enable_mdns_offload) {
10000 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
10001 if (VOS_IS_STATUS_SUCCESS(status))
10002 {
10003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10004 ("HDD MDNS Server Offload Failed!!"));
10005 return -EINVAL;
10006 }
10007 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
10008 status = vos_wait_single_event(&pHostapdAdapter->
10009 mdns_status.vos_event, 2000);
10010 if (!VOS_IS_STATUS_SUCCESS(status) ||
10011 pHostapdAdapter->mdns_status.mdns_enable_status ||
10012 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
10013 pHostapdAdapter->mdns_status.mdns_resp_status)
10014 {
10015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10016 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
10017 pHostapdAdapter->mdns_status.mdns_enable_status,
10018 pHostapdAdapter->mdns_status.mdns_fqdn_status,
10019 pHostapdAdapter->mdns_status.mdns_resp_status);
10020 return -EINVAL;
10021 }
10022 }
10023#endif /* MDNS_OFFLOAD */
10024 } else {
10025 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10026 ("DHCP Disabled ini %d, FW %d"),
10027 iniConfig->enable_dhcp_srv_offload,
10028 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053010029 }
10030#endif /* DHCP_SERVER_OFFLOAD */
10031
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010032#ifdef WLAN_FEATURE_P2P_DEBUG
10033 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
10034 {
10035 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
10036 {
10037 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10038 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010039 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010040 }
10041 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
10042 {
10043 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10044 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010045 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010046 }
10047 }
10048#endif
10049
Jeff Johnson295189b2012-06-20 16:38:30 -070010050 pHostapdState->bCommit = TRUE;
10051 EXIT();
10052
10053 return 0;
10054}
10055
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010056#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010057static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010058 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070010059 struct beacon_parameters *params)
10060{
10061 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010062 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010063 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010064
10065 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010066
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010067 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10068 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
10069 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010070 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
10071 hdd_device_modetoString(pAdapter->device_mode),
10072 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010073
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010074 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10075 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010076 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010077 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010078 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010079 }
10080
Agarwal Ashish51325b52014-06-16 16:50:49 +053010081 if (vos_max_concurrent_connections_reached()) {
10082 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10083 return -EINVAL;
10084 }
10085
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010086 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010087 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010088 )
10089 {
10090 beacon_data_t *old,*new;
10091
10092 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010093
Jeff Johnson295189b2012-06-20 16:38:30 -070010094 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010095 {
10096 hddLog(VOS_TRACE_LEVEL_WARN,
10097 FL("already beacon info added to session(%d)"),
10098 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010099 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010100 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010101
10102 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10103
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010104 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070010105 {
10106 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010107 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010108 return -EINVAL;
10109 }
10110
10111 pAdapter->sessionCtx.ap.beacon = new;
10112
10113 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10114 }
10115
10116 EXIT();
10117 return status;
10118}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010119
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010120static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
10121 struct net_device *dev,
10122 struct beacon_parameters *params)
10123{
10124 int ret;
10125
10126 vos_ssr_protect(__func__);
10127 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
10128 vos_ssr_unprotect(__func__);
10129
10130 return ret;
10131}
10132
10133static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010134 struct net_device *dev,
10135 struct beacon_parameters *params)
10136{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010137 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010138 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10139 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010140 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010141
10142 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010143
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010144 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10145 TRACE_CODE_HDD_CFG80211_SET_BEACON,
10146 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
10147 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10148 __func__, hdd_device_modetoString(pAdapter->device_mode),
10149 pAdapter->device_mode);
10150
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010151 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10152 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010153 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010154 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010155 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010156 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010157
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010158 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010159 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010160 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010161 {
10162 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010163
Jeff Johnson295189b2012-06-20 16:38:30 -070010164 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010165
Jeff Johnson295189b2012-06-20 16:38:30 -070010166 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010167 {
10168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10169 FL("session(%d) old and new heads points to NULL"),
10170 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010171 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010172 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010173
10174 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10175
10176 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010177 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010178 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010179 return -EINVAL;
10180 }
10181
10182 pAdapter->sessionCtx.ap.beacon = new;
10183
10184 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10185 }
10186
10187 EXIT();
10188 return status;
10189}
10190
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010191static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
10192 struct net_device *dev,
10193 struct beacon_parameters *params)
10194{
10195 int ret;
10196
10197 vos_ssr_protect(__func__);
10198 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
10199 vos_ssr_unprotect(__func__);
10200
10201 return ret;
10202}
10203
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010204#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10205
10206#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010207static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010208 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010209#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010210static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010211 struct net_device *dev)
10212#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010213{
10214 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070010215 hdd_context_t *pHddCtx = NULL;
10216 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010217 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010218 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010219
10220 ENTER();
10221
10222 if (NULL == pAdapter)
10223 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010225 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010226 return -ENODEV;
10227 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010228
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010229 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10230 TRACE_CODE_HDD_CFG80211_STOP_AP,
10231 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010232 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10233 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010234 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010235 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010236 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070010237 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010238
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010239 pScanInfo = &pHddCtx->scan_info;
10240
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010241 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10242 __func__, hdd_device_modetoString(pAdapter->device_mode),
10243 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010244
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010245 ret = wlan_hdd_scan_abort(pAdapter);
10246
Girish Gowli4bf7a632014-06-12 13:42:11 +053010247 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070010248 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10250 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010251
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010252 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070010253 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10255 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080010256
Jeff Johnsone7245742012-09-05 17:12:55 -070010257 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010258 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070010259 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010260 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010261 }
10262
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010263 /* Delete all associated STAs before stopping AP/P2P GO */
10264 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053010265 hdd_hostapd_stop(dev);
10266
Jeff Johnson295189b2012-06-20 16:38:30 -070010267 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010268 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010269 )
10270 {
10271 beacon_data_t *old;
10272
10273 old = pAdapter->sessionCtx.ap.beacon;
10274
10275 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010276 {
10277 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10278 FL("session(%d) beacon data points to NULL"),
10279 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010280 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010281 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010282
Jeff Johnson295189b2012-06-20 16:38:30 -070010283 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010284
10285 mutex_lock(&pHddCtx->sap_lock);
10286 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10287 {
Jeff Johnson4416a782013-03-25 14:17:50 -070010288 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010289 {
10290 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10291
10292 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10293
10294 if (!VOS_IS_STATUS_SUCCESS(status))
10295 {
10296 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010297 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010298 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010299 }
10300 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010301 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010302 /* BSS stopped, clear the active sessions for this device mode */
10303 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010304 }
10305 mutex_unlock(&pHddCtx->sap_lock);
10306
10307 if(status != VOS_STATUS_SUCCESS)
10308 {
10309 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010310 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010311 return -EINVAL;
10312 }
10313
Jeff Johnson4416a782013-03-25 14:17:50 -070010314 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010315 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
10316 ==eHAL_STATUS_FAILURE)
10317 {
10318 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010319 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010320 }
10321
Jeff Johnson4416a782013-03-25 14:17:50 -070010322 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010323 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10324 eANI_BOOLEAN_FALSE) )
10325 {
10326 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010327 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010328 }
10329
10330 // Reset WNI_CFG_PROBE_RSP Flags
10331 wlan_hdd_reset_prob_rspies(pAdapter);
10332
10333 pAdapter->sessionCtx.ap.beacon = NULL;
10334 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010335#ifdef WLAN_FEATURE_P2P_DEBUG
10336 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
10337 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
10338 {
10339 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
10340 "GO got removed");
10341 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
10342 }
10343#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010344 }
10345 EXIT();
10346 return status;
10347}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010348
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010349#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10350static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
10351 struct net_device *dev)
10352{
10353 int ret;
10354
10355 vos_ssr_protect(__func__);
10356 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
10357 vos_ssr_unprotect(__func__);
10358
10359 return ret;
10360}
10361#else
10362static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
10363 struct net_device *dev)
10364{
10365 int ret;
10366
10367 vos_ssr_protect(__func__);
10368 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
10369 vos_ssr_unprotect(__func__);
10370
10371 return ret;
10372}
10373#endif
10374
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010375#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
10376
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010377static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010378 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010379 struct cfg80211_ap_settings *params)
10380{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010381 hdd_adapter_t *pAdapter;
10382 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010383 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010384
10385 ENTER();
10386
Girish Gowlib143d7a2015-02-18 19:39:55 +053010387 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010388 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010389 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053010390 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010391 return -ENODEV;
10392 }
10393
10394 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10395 if (NULL == pAdapter)
10396 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010398 "%s: HDD adapter is Null", __func__);
10399 return -ENODEV;
10400 }
10401
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010402 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10403 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
10404 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010405 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
10406 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010407 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010408 "%s: HDD adapter magic is invalid", __func__);
10409 return -ENODEV;
10410 }
10411
10412 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010413 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010414 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010415 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010416 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010417 }
10418
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010419 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
10420 __func__, hdd_device_modetoString(pAdapter->device_mode),
10421 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010422
10423 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010424 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010425 )
10426 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010427 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010428
10429 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010430
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010431 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010432 {
10433 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10434 FL("already beacon info added to session(%d)"),
10435 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010436 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010437 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010438
Girish Gowlib143d7a2015-02-18 19:39:55 +053010439#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10440 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10441 &new,
10442 &params->beacon);
10443#else
10444 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10445 &new,
10446 &params->beacon,
10447 params->dtim_period);
10448#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010449
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010450 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010451 {
10452 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010453 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010454 return -EINVAL;
10455 }
10456 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010457#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010458 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10459#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10460 params->channel, params->channel_type);
10461#else
10462 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10463#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010464#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010465 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010466 params->ssid_len, params->hidden_ssid,
10467 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010468 }
10469
10470 EXIT();
10471 return status;
10472}
10473
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010474static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10475 struct net_device *dev,
10476 struct cfg80211_ap_settings *params)
10477{
10478 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010479
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010480 vos_ssr_protect(__func__);
10481 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10482 vos_ssr_unprotect(__func__);
10483
10484 return ret;
10485}
10486
10487static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010488 struct net_device *dev,
10489 struct cfg80211_beacon_data *params)
10490{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010491 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010492 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010493 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010494
10495 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010496
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010497 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10498 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10499 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010500 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010501 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010502
10503 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10504 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010505 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010506 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010507 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010508 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010509
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010510 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010511 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010512 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010513 {
10514 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010515
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010516 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010517
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010518 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010519 {
10520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10521 FL("session(%d) beacon data points to NULL"),
10522 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010523 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010524 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010525
10526 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10527
10528 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010529 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010530 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010531 return -EINVAL;
10532 }
10533
10534 pAdapter->sessionCtx.ap.beacon = new;
10535
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010536 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10537 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010538 }
10539
10540 EXIT();
10541 return status;
10542}
10543
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010544static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10545 struct net_device *dev,
10546 struct cfg80211_beacon_data *params)
10547{
10548 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010549
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010550 vos_ssr_protect(__func__);
10551 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10552 vos_ssr_unprotect(__func__);
10553
10554 return ret;
10555}
10556
10557#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010558
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010559static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010560 struct net_device *dev,
10561 struct bss_parameters *params)
10562{
10563 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010564 hdd_context_t *pHddCtx;
10565 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010566
10567 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010568
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010569 if (NULL == pAdapter)
10570 {
10571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10572 "%s: HDD adapter is Null", __func__);
10573 return -ENODEV;
10574 }
10575 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010576 ret = wlan_hdd_validate_context(pHddCtx);
10577 if (0 != ret)
10578 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010579 return ret;
10580 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010581 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10582 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
10583 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010584 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10585 __func__, hdd_device_modetoString(pAdapter->device_mode),
10586 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010587
10588 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010589 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010590 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010591 {
10592 /* ap_isolate == -1 means that in change bss, upper layer doesn't
10593 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010594 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070010595 {
10596 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010597 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010598 }
10599
10600 EXIT();
10601 return 0;
10602}
10603
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010604static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
10605 struct net_device *dev,
10606 struct bss_parameters *params)
10607{
10608 int ret;
10609
10610 vos_ssr_protect(__func__);
10611 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
10612 vos_ssr_unprotect(__func__);
10613
10614 return ret;
10615}
Kiet Lam10841362013-11-01 11:36:50 +053010616/* FUNCTION: wlan_hdd_change_country_code_cd
10617* to wait for contry code completion
10618*/
10619void* wlan_hdd_change_country_code_cb(void *pAdapter)
10620{
10621 hdd_adapter_t *call_back_pAdapter = pAdapter;
10622 complete(&call_back_pAdapter->change_country_code);
10623 return NULL;
10624}
10625
Jeff Johnson295189b2012-06-20 16:38:30 -070010626/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010627 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070010628 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
10629 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010630int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010631 struct net_device *ndev,
10632 enum nl80211_iftype type,
10633 u32 *flags,
10634 struct vif_params *params
10635 )
10636{
10637 struct wireless_dev *wdev;
10638 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010639 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070010640 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010641 tCsrRoamProfile *pRoamProfile = NULL;
10642 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010643 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010644 eMib_dot11DesiredBssType connectedBssType;
10645 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010646 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010647
10648 ENTER();
10649
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010650 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010651 {
10652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10653 "%s: Adapter context is null", __func__);
10654 return VOS_STATUS_E_FAILURE;
10655 }
10656
10657 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10658 if (!pHddCtx)
10659 {
10660 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10661 "%s: HDD context is null", __func__);
10662 return VOS_STATUS_E_FAILURE;
10663 }
10664
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010665 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10666 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
10667 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010668 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010669 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010670 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010671 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010672 }
10673
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010674 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10675 __func__, hdd_device_modetoString(pAdapter->device_mode),
10676 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010677
Agarwal Ashish51325b52014-06-16 16:50:49 +053010678 if (vos_max_concurrent_connections_reached()) {
10679 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10680 return -EINVAL;
10681 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010682 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070010683 wdev = ndev->ieee80211_ptr;
10684
10685#ifdef WLAN_BTAMP_FEATURE
10686 if((NL80211_IFTYPE_P2P_CLIENT == type)||
10687 (NL80211_IFTYPE_ADHOC == type)||
10688 (NL80211_IFTYPE_AP == type)||
10689 (NL80211_IFTYPE_P2P_GO == type))
10690 {
10691 pHddCtx->isAmpAllowed = VOS_FALSE;
10692 // stop AMP traffic
10693 status = WLANBAP_StopAmp();
10694 if(VOS_STATUS_SUCCESS != status )
10695 {
10696 pHddCtx->isAmpAllowed = VOS_TRUE;
10697 hddLog(VOS_TRACE_LEVEL_FATAL,
10698 "%s: Failed to stop AMP", __func__);
10699 return -EINVAL;
10700 }
10701 }
10702#endif //WLAN_BTAMP_FEATURE
10703 /* Reset the current device mode bit mask*/
10704 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10705
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053010706 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
10707 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
10708 (type == NL80211_IFTYPE_P2P_GO)))
10709 {
10710 /* Notify Mode change in case of concurrency.
10711 * Below function invokes TDLS teardown Functionality Since TDLS is
10712 * not Supported in case of concurrency i.e Once P2P session
10713 * is detected disable offchannel and teardown TDLS links
10714 */
10715 hddLog(LOG1,
10716 FL("Device mode = %d Interface type = %d"),
10717 pAdapter->device_mode, type);
10718 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
10719 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053010720
Jeff Johnson295189b2012-06-20 16:38:30 -070010721 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010722 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070010723 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010724 )
10725 {
10726 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010727 if (!pWextState)
10728 {
10729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10730 "%s: pWextState is null", __func__);
10731 return VOS_STATUS_E_FAILURE;
10732 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010733 pRoamProfile = &pWextState->roamProfile;
10734 LastBSSType = pRoamProfile->BSSType;
10735
10736 switch (type)
10737 {
10738 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010739 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010740 hddLog(VOS_TRACE_LEVEL_INFO,
10741 "%s: setting interface Type to INFRASTRUCTURE", __func__);
10742 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010743#ifdef WLAN_FEATURE_11AC
10744 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
10745 {
10746 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
10747 }
10748#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010749 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070010750 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010751 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010752 //Check for sub-string p2p to confirm its a p2p interface
10753 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010754 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053010755#ifdef FEATURE_WLAN_TDLS
10756 mutex_lock(&pHddCtx->tdls_lock);
10757 wlan_hdd_tdls_exit(pAdapter, TRUE);
10758 mutex_unlock(&pHddCtx->tdls_lock);
10759#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010760 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10761 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10762 }
10763 else
10764 {
10765 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010766 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010767 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010768 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053010769
Jeff Johnson295189b2012-06-20 16:38:30 -070010770 case NL80211_IFTYPE_ADHOC:
10771 hddLog(VOS_TRACE_LEVEL_INFO,
10772 "%s: setting interface Type to ADHOC", __func__);
10773 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
10774 pRoamProfile->phyMode =
10775 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070010776 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010777 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053010778 hdd_set_ibss_ops( pAdapter );
10779 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053010780
10781 status = hdd_sta_id_hash_attach(pAdapter);
10782 if (VOS_STATUS_SUCCESS != status) {
10783 hddLog(VOS_TRACE_LEVEL_ERROR,
10784 FL("Failed to initialize hash for IBSS"));
10785 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010786 break;
10787
10788 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010789 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010790 {
10791 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10792 "%s: setting interface Type to %s", __func__,
10793 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
10794
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010795 //Cancel any remain on channel for GO mode
10796 if (NL80211_IFTYPE_P2P_GO == type)
10797 {
10798 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
10799 }
Mohit Khanna0f232092012-09-11 14:46:08 -070010800 if (NL80211_IFTYPE_AP == type)
10801 {
10802 /* As Loading WLAN Driver one interface being created for p2p device
10803 * address. This will take one HW STA and the max number of clients
10804 * that can connect to softAP will be reduced by one. so while changing
10805 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
10806 * interface as it is not required in SoftAP mode.
10807 */
10808
10809 // Get P2P Adapter
10810 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
10811
10812 if (pP2pAdapter)
10813 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010814 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053010815 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070010816 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
10817 }
10818 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053010819 //Disable IMPS & BMPS for SAP/GO
10820 if(VOS_STATUS_E_FAILURE ==
10821 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
10822 {
10823 //Fail to Exit BMPS
10824 VOS_ASSERT(0);
10825 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053010826
10827 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
10828
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010829#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070010830
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010831 /* A Mutex Lock is introduced while changing the mode to
10832 * protect the concurrent access for the Adapters by TDLS
10833 * module.
10834 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010835 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010836#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010837 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053010838 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010839 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070010840 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10841 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010842#ifdef FEATURE_WLAN_TDLS
10843 mutex_unlock(&pHddCtx->tdls_lock);
10844#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010845 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
10846 (pConfig->apRandomBssidEnabled))
10847 {
10848 /* To meet Android requirements create a randomized
10849 MAC address of the form 02:1A:11:Fx:xx:xx */
10850 get_random_bytes(&ndev->dev_addr[3], 3);
10851 ndev->dev_addr[0] = 0x02;
10852 ndev->dev_addr[1] = 0x1A;
10853 ndev->dev_addr[2] = 0x11;
10854 ndev->dev_addr[3] |= 0xF0;
10855 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
10856 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080010857 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
10858 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010859 }
10860
Jeff Johnson295189b2012-06-20 16:38:30 -070010861 hdd_set_ap_ops( pAdapter->dev );
10862
Kiet Lam10841362013-11-01 11:36:50 +053010863 /* This is for only SAP mode where users can
10864 * control country through ini.
10865 * P2P GO follows station country code
10866 * acquired during the STA scanning. */
10867 if((NL80211_IFTYPE_AP == type) &&
10868 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
10869 {
10870 int status = 0;
10871 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
10872 "%s: setting country code from INI ", __func__);
10873 init_completion(&pAdapter->change_country_code);
10874 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
10875 (void *)(tSmeChangeCountryCallback)
10876 wlan_hdd_change_country_code_cb,
10877 pConfig->apCntryCode, pAdapter,
10878 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010879 eSIR_FALSE,
10880 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053010881 if (eHAL_STATUS_SUCCESS == status)
10882 {
10883 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010884 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053010885 &pAdapter->change_country_code,
10886 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010887 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053010888 {
10889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010890 FL("SME Timed out while setting country code %ld"),
10891 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080010892
10893 if (pHddCtx->isLogpInProgress)
10894 {
10895 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10896 "%s: LOGP in Progress. Ignore!!!", __func__);
10897 return -EAGAIN;
10898 }
Kiet Lam10841362013-11-01 11:36:50 +053010899 }
10900 }
10901 else
10902 {
10903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010904 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053010905 return -EINVAL;
10906 }
10907 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010908 status = hdd_init_ap_mode(pAdapter);
10909 if(status != VOS_STATUS_SUCCESS)
10910 {
10911 hddLog(VOS_TRACE_LEVEL_FATAL,
10912 "%s: Error initializing the ap mode", __func__);
10913 return -EINVAL;
10914 }
10915 hdd_set_conparam(1);
10916
Nirav Shah7e3c8132015-06-22 23:51:42 +053010917 status = hdd_sta_id_hash_attach(pAdapter);
10918 if (VOS_STATUS_SUCCESS != status)
10919 {
10920 hddLog(VOS_TRACE_LEVEL_ERROR,
10921 FL("Failed to initialize hash for AP"));
10922 return -EINVAL;
10923 }
10924
Jeff Johnson295189b2012-06-20 16:38:30 -070010925 /*interface type changed update in wiphy structure*/
10926 if(wdev)
10927 {
10928 wdev->iftype = type;
10929 pHddCtx->change_iface = type;
10930 }
10931 else
10932 {
10933 hddLog(VOS_TRACE_LEVEL_ERROR,
10934 "%s: ERROR !!!! Wireless dev is NULL", __func__);
10935 return -EINVAL;
10936 }
10937 goto done;
10938 }
10939
10940 default:
10941 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10942 __func__);
10943 return -EOPNOTSUPP;
10944 }
10945 }
10946 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010947 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010948 )
10949 {
10950 switch(type)
10951 {
10952 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010953 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010954 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053010955
10956 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010957#ifdef FEATURE_WLAN_TDLS
10958
10959 /* A Mutex Lock is introduced while changing the mode to
10960 * protect the concurrent access for the Adapters by TDLS
10961 * module.
10962 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010963 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010964#endif
c_hpothu002231a2015-02-05 14:58:51 +053010965 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010966 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010967 //Check for sub-string p2p to confirm its a p2p interface
10968 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010969 {
10970 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10971 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10972 }
10973 else
10974 {
10975 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010976 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010977 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053010978
10979 /* set con_mode to STA only when no SAP concurrency mode */
10980 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
10981 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070010982 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010983 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
10984 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010985#ifdef FEATURE_WLAN_TDLS
10986 mutex_unlock(&pHddCtx->tdls_lock);
10987#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053010988 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070010989 if( VOS_STATUS_SUCCESS != status )
10990 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070010991 /* In case of JB, for P2P-GO, only change interface will be called,
10992 * This is the right place to enable back bmps_imps()
10993 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010994 if (pHddCtx->hdd_wlan_suspended)
10995 {
10996 hdd_set_pwrparams(pHddCtx);
10997 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010998 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010999 goto done;
11000 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011001 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011002 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011003 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11004 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011005 goto done;
11006 default:
11007 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11008 __func__);
11009 return -EOPNOTSUPP;
11010
11011 }
11012
11013 }
11014 else
11015 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011016 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
11017 __func__, hdd_device_modetoString(pAdapter->device_mode),
11018 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011019 return -EOPNOTSUPP;
11020 }
11021
11022
11023 if(pRoamProfile)
11024 {
11025 if ( LastBSSType != pRoamProfile->BSSType )
11026 {
11027 /*interface type changed update in wiphy structure*/
11028 wdev->iftype = type;
11029
11030 /*the BSS mode changed, We need to issue disconnect
11031 if connected or in IBSS disconnect state*/
11032 if ( hdd_connGetConnectedBssType(
11033 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
11034 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
11035 {
11036 /*need to issue a disconnect to CSR.*/
11037 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11038 if( eHAL_STATUS_SUCCESS ==
11039 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11040 pAdapter->sessionId,
11041 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11042 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011043 ret = wait_for_completion_interruptible_timeout(
11044 &pAdapter->disconnect_comp_var,
11045 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11046 if (ret <= 0)
11047 {
11048 hddLog(VOS_TRACE_LEVEL_ERROR,
11049 FL("wait on disconnect_comp_var failed %ld"), ret);
11050 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011051 }
11052 }
11053 }
11054 }
11055
11056done:
11057 /*set bitmask based on updated value*/
11058 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070011059
11060 /* Only STA mode support TM now
11061 * all other mode, TM feature should be disabled */
11062 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
11063 (~VOS_STA & pHddCtx->concurrency_mode) )
11064 {
11065 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
11066 }
11067
Jeff Johnson295189b2012-06-20 16:38:30 -070011068#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011069 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011070 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070011071 {
11072 //we are ok to do AMP
11073 pHddCtx->isAmpAllowed = VOS_TRUE;
11074 }
11075#endif //WLAN_BTAMP_FEATURE
11076 EXIT();
11077 return 0;
11078}
11079
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011080/*
11081 * FUNCTION: wlan_hdd_cfg80211_change_iface
11082 * wrapper function to protect the actual implementation from SSR.
11083 */
11084int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
11085 struct net_device *ndev,
11086 enum nl80211_iftype type,
11087 u32 *flags,
11088 struct vif_params *params
11089 )
11090{
11091 int ret;
11092
11093 vos_ssr_protect(__func__);
11094 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
11095 vos_ssr_unprotect(__func__);
11096
11097 return ret;
11098}
11099
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011100#ifdef FEATURE_WLAN_TDLS
11101static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011102 struct net_device *dev,
11103#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11104 const u8 *mac,
11105#else
11106 u8 *mac,
11107#endif
11108 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011109{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011110 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011111 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011112 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011113 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011114 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011115 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011116
11117 ENTER();
11118
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011119 if (!dev) {
11120 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
11121 return -EINVAL;
11122 }
11123
11124 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11125 if (!pAdapter) {
11126 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
11127 return -EINVAL;
11128 }
11129
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011130 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011131 {
11132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11133 "Invalid arguments");
11134 return -EINVAL;
11135 }
Hoonki Lee27511902013-03-14 18:19:06 -070011136
11137 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
11138 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
11139 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070011141 "%s: TDLS mode is disabled OR not enabled in FW."
11142 MAC_ADDRESS_STR " Request declined.",
11143 __func__, MAC_ADDR_ARRAY(mac));
11144 return -ENOTSUPP;
11145 }
11146
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011147 if (pHddCtx->isLogpInProgress)
11148 {
11149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11150 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053011151 wlan_hdd_tdls_set_link_status(pAdapter,
11152 mac,
11153 eTDLS_LINK_IDLE,
11154 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011155 return -EBUSY;
11156 }
11157
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011158 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053011159 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011160
11161 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011163 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
11164 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011165 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011166 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011167 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011168
11169 /* in add station, we accept existing valid staId if there is */
11170 if ((0 == update) &&
11171 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
11172 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011173 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011174 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011175 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011176 " link_status %d. staId %d. add station ignored.",
11177 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011178 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011179 return 0;
11180 }
11181 /* in change station, we accept only when staId is valid */
11182 if ((1 == update) &&
11183 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
11184 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
11185 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011186 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011188 "%s: " MAC_ADDRESS_STR
11189 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011190 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
11191 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
11192 mutex_unlock(&pHddCtx->tdls_lock);
11193 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011194 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011195 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011196
11197 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053011198 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011199 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11201 "%s: " MAC_ADDRESS_STR
11202 " TDLS setup is ongoing. Request declined.",
11203 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070011204 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011205 }
11206
11207 /* first to check if we reached to maximum supported TDLS peer.
11208 TODO: for now, return -EPERM looks working fine,
11209 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011210 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
11211 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011212 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11214 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011215 " TDLS Max peer already connected. Request declined."
11216 " Num of peers (%d), Max allowed (%d).",
11217 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
11218 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011219 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011220 }
11221 else
11222 {
11223 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011224 mutex_lock(&pHddCtx->tdls_lock);
11225 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011226 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011227 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011228 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011229 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11230 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
11231 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011232 return -EPERM;
11233 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011234 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011235 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011236 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053011237 wlan_hdd_tdls_set_link_status(pAdapter,
11238 mac,
11239 eTDLS_LINK_CONNECTING,
11240 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011241
Jeff Johnsond75fe012013-04-06 10:53:06 -070011242 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011243 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011244 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011246 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011247 if(StaParams->htcap_present)
11248 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011250 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011252 "ht_capa->extended_capabilities: %0x",
11253 StaParams->HTCap.extendedHtCapInfo);
11254 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011256 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011257 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011258 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011259 if(StaParams->vhtcap_present)
11260 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011262 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
11263 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
11264 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
11265 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011266 {
11267 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011269 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011270 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011271 "[%d]: %x ", i, StaParams->supported_rates[i]);
11272 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070011273 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011274 else if ((1 == update) && (NULL == StaParams))
11275 {
11276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11277 "%s : update is true, but staParams is NULL. Error!", __func__);
11278 return -EPERM;
11279 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011280
11281 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
11282
11283 if (!update)
11284 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011285 /*Before adding sta make sure that device exited from BMPS*/
11286 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
11287 {
11288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11289 "%s: Adding tdls peer sta. Disable BMPS", __func__);
11290 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
11291 if (status != VOS_STATUS_SUCCESS) {
11292 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
11293 }
11294 }
11295
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011296 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011297 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011298 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011299 hddLog(VOS_TRACE_LEVEL_ERROR,
11300 FL("Failed to add TDLS peer STA. Enable Bmps"));
11301 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011302 return -EPERM;
11303 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011304 }
11305 else
11306 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011307 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011308 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011309 if (ret != eHAL_STATUS_SUCCESS) {
11310 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
11311 return -EPERM;
11312 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011313 }
11314
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011315 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011316 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
11317
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011318 mutex_lock(&pHddCtx->tdls_lock);
11319 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
11320
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011321 if ((pTdlsPeer != NULL) &&
11322 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011323 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011324 hddLog(VOS_TRACE_LEVEL_ERROR,
11325 FL("peer link status %u"), pTdlsPeer->link_status);
11326 mutex_unlock(&pHddCtx->tdls_lock);
11327 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011328 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011329 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011330
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011331 if (ret <= 0)
11332 {
11333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11334 "%s: timeout waiting for tdls add station indication %ld",
11335 __func__, ret);
11336 goto error;
11337 }
11338
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011339 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
11340 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011342 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011343 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011344 }
11345
11346 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070011347
11348error:
Atul Mittal115287b2014-07-08 13:26:33 +053011349 wlan_hdd_tdls_set_link_status(pAdapter,
11350 mac,
11351 eTDLS_LINK_IDLE,
11352 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011353 return -EPERM;
11354
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011355}
11356#endif
11357
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011358static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011359 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011360#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11361 const u8 *mac,
11362#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011363 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011364#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011365 struct station_parameters *params)
11366{
11367 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011368 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011369 hdd_context_t *pHddCtx;
11370 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011371 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011372 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011373#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011374 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011375 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011376 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011377 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011378#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011379
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011380 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011381
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011382 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011383 if ((NULL == pAdapter))
11384 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011386 "invalid adapter ");
11387 return -EINVAL;
11388 }
11389
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011390 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11391 TRACE_CODE_HDD_CHANGE_STATION,
11392 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053011393 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011394
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011395 ret = wlan_hdd_validate_context(pHddCtx);
11396 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053011397 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011398 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011399 }
11400
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011401 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11402
11403 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011404 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11406 "invalid HDD station context");
11407 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011408 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011409 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
11410
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011411 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11412 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070011413 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011414 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070011415 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011416 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070011417 WLANTL_STA_AUTHENTICATED);
11418
Gopichand Nakkala29149562013-05-10 21:43:41 +053011419 if (status != VOS_STATUS_SUCCESS)
11420 {
11421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11422 "%s: Not able to change TL state to AUTHENTICATED", __func__);
11423 return -EINVAL;
11424 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011425 }
11426 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070011427 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
11428 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011429#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011430 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11431 StaParams.capability = params->capability;
11432 StaParams.uapsd_queues = params->uapsd_queues;
11433 StaParams.max_sp = params->max_sp;
11434
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011435 /* Convert (first channel , number of channels) tuple to
11436 * the total list of channels. This goes with the assumption
11437 * that if the first channel is < 14, then the next channels
11438 * are an incremental of 1 else an incremental of 4 till the number
11439 * of channels.
11440 */
11441 if (0 != params->supported_channels_len) {
11442 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11443 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11444 {
11445 int wifi_chan_index;
11446 StaParams.supported_channels[j] = params->supported_channels[i];
11447 wifi_chan_index =
11448 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11449 no_of_channels = params->supported_channels[i+1];
11450 for(k=1; k <= no_of_channels; k++)
11451 {
11452 StaParams.supported_channels[j+1] =
11453 StaParams.supported_channels[j] + wifi_chan_index;
11454 j+=1;
11455 }
11456 }
11457 StaParams.supported_channels_len = j;
11458 }
11459 vos_mem_copy(StaParams.supported_oper_classes,
11460 params->supported_oper_classes,
11461 params->supported_oper_classes_len);
11462 StaParams.supported_oper_classes_len =
11463 params->supported_oper_classes_len;
11464
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011465 if (0 != params->ext_capab_len)
11466 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
11467 sizeof(StaParams.extn_capability));
11468
11469 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011470 {
11471 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011472 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011473 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011474
11475 StaParams.supported_rates_len = params->supported_rates_len;
11476
11477 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11478 * The supported_rates array , for all the structures propogating till Add Sta
11479 * to the firmware has to be modified , if the supplicant (ieee80211) is
11480 * modified to send more rates.
11481 */
11482
11483 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11484 */
11485 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11486 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11487
11488 if (0 != StaParams.supported_rates_len) {
11489 int i = 0;
11490 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11491 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011493 "Supported Rates with Length %d", StaParams.supported_rates_len);
11494 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011495 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011496 "[%d]: %0x", i, StaParams.supported_rates[i]);
11497 }
11498
11499 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011500 {
11501 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011502 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011503 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011504
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011505 if (0 != params->ext_capab_len ) {
11506 /*Define A Macro : TODO Sunil*/
11507 if ((1<<4) & StaParams.extn_capability[3]) {
11508 isBufSta = 1;
11509 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011510 /* TDLS Channel Switching Support */
11511 if ((1<<6) & StaParams.extn_capability[3]) {
11512 isOffChannelSupported = 1;
11513 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011514 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011515
11516 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053011517 (params->ht_capa || params->vht_capa ||
11518 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011519 /* TDLS Peer is WME/QoS capable */
11520 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011521
11522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11523 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
11524 __func__, isQosWmmSta, StaParams.htcap_present);
11525
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011526 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11527 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011528 isOffChannelSupported,
11529 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011530
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011531 if (VOS_STATUS_SUCCESS != status) {
11532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11533 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11534 return -EINVAL;
11535 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011536 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11537
11538 if (VOS_STATUS_SUCCESS != status) {
11539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11540 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11541 return -EINVAL;
11542 }
11543 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011544#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011545 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011546 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011547 return status;
11548}
11549
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011550#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11551static int wlan_hdd_change_station(struct wiphy *wiphy,
11552 struct net_device *dev,
11553 const u8 *mac,
11554 struct station_parameters *params)
11555#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011556static int wlan_hdd_change_station(struct wiphy *wiphy,
11557 struct net_device *dev,
11558 u8 *mac,
11559 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011560#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011561{
11562 int ret;
11563
11564 vos_ssr_protect(__func__);
11565 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11566 vos_ssr_unprotect(__func__);
11567
11568 return ret;
11569}
11570
Jeff Johnson295189b2012-06-20 16:38:30 -070011571/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011572 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011573 * This function is used to initialize the key information
11574 */
11575#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011576static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011577 struct net_device *ndev,
11578 u8 key_index, bool pairwise,
11579 const u8 *mac_addr,
11580 struct key_params *params
11581 )
11582#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011583static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011584 struct net_device *ndev,
11585 u8 key_index, const u8 *mac_addr,
11586 struct key_params *params
11587 )
11588#endif
11589{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011590 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011591 tCsrRoamSetKey setKey;
11592 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011593 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011594 v_U32_t roamId= 0xFF;
11595 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011596 hdd_hostapd_state_t *pHostapdState;
11597 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011598 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011599 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011600
11601 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011602
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011603 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11604 TRACE_CODE_HDD_CFG80211_ADD_KEY,
11605 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011606 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11607 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011608 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011609 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011610 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011611 }
11612
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011613 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11614 __func__, hdd_device_modetoString(pAdapter->device_mode),
11615 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011616
11617 if (CSR_MAX_NUM_KEY <= key_index)
11618 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011619 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011620 key_index);
11621
11622 return -EINVAL;
11623 }
11624
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011625 if (CSR_MAX_KEY_LEN < params->key_len)
11626 {
11627 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
11628 params->key_len);
11629
11630 return -EINVAL;
11631 }
11632
11633 hddLog(VOS_TRACE_LEVEL_INFO,
11634 "%s: called with key index = %d & key length %d",
11635 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011636
11637 /*extract key idx, key len and key*/
11638 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11639 setKey.keyId = key_index;
11640 setKey.keyLength = params->key_len;
11641 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
11642
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011643 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011644 {
11645 case WLAN_CIPHER_SUITE_WEP40:
11646 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11647 break;
11648
11649 case WLAN_CIPHER_SUITE_WEP104:
11650 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
11651 break;
11652
11653 case WLAN_CIPHER_SUITE_TKIP:
11654 {
11655 u8 *pKey = &setKey.Key[0];
11656 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
11657
11658 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
11659
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011660 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070011661
11662 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011663 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011664 |--------------|----------|----------|
11665 <---16bytes---><--8bytes--><--8bytes-->
11666
11667 */
11668 /*Sme expects the 32 bytes key to be in the below order
11669
11670 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011671 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011672 |--------------|----------|----------|
11673 <---16bytes---><--8bytes--><--8bytes-->
11674 */
11675 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011676 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070011677
11678 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011679 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011680
11681 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011682 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011683
11684
11685 break;
11686 }
11687
11688 case WLAN_CIPHER_SUITE_CCMP:
11689 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
11690 break;
11691
11692#ifdef FEATURE_WLAN_WAPI
11693 case WLAN_CIPHER_SUITE_SMS4:
11694 {
11695 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11696 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
11697 params->key, params->key_len);
11698 return 0;
11699 }
11700#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011701
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011702#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011703 case WLAN_CIPHER_SUITE_KRK:
11704 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
11705 break;
11706#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011707
11708#ifdef WLAN_FEATURE_11W
11709 case WLAN_CIPHER_SUITE_AES_CMAC:
11710 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070011711 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070011712#endif
11713
Jeff Johnson295189b2012-06-20 16:38:30 -070011714 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011715 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011716 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011717 status = -EOPNOTSUPP;
11718 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011719 }
11720
11721 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
11722 __func__, setKey.encType);
11723
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011724 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070011725#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11726 (!pairwise)
11727#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011728 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070011729#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011730 )
11731 {
11732 /* set group key*/
11733 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11734 "%s- %d: setting Broadcast key",
11735 __func__, __LINE__);
11736 setKey.keyDirection = eSIR_RX_ONLY;
11737 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11738 }
11739 else
11740 {
11741 /* set pairwise key*/
11742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11743 "%s- %d: setting pairwise key",
11744 __func__, __LINE__);
11745 setKey.keyDirection = eSIR_TX_RX;
11746 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11747 }
11748 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
11749 {
11750 setKey.keyDirection = eSIR_TX_RX;
11751 /*Set the group key*/
11752 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11753 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070011754
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011755 if ( 0 != status )
11756 {
11757 hddLog(VOS_TRACE_LEVEL_ERROR,
11758 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011759 status = -EINVAL;
11760 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011761 }
11762 /*Save the keys here and call sme_RoamSetKey for setting
11763 the PTK after peer joins the IBSS network*/
11764 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
11765 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011766 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011767 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053011768 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
11769 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
11770 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011771 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011772 if( pHostapdState->bssState == BSS_START )
11773 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011774 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11775 vos_status = wlan_hdd_check_ula_done(pAdapter);
11776
11777 if ( vos_status != VOS_STATUS_SUCCESS )
11778 {
11779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11780 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11781 __LINE__, vos_status );
11782
11783 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11784
11785 status = -EINVAL;
11786 goto end;
11787 }
11788
Jeff Johnson295189b2012-06-20 16:38:30 -070011789 status = WLANSAP_SetKeySta( pVosContext, &setKey);
11790
11791 if ( status != eHAL_STATUS_SUCCESS )
11792 {
11793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11794 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11795 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011796 status = -EINVAL;
11797 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011798 }
11799 }
11800
11801 /* Saving WEP keys */
11802 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
11803 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
11804 {
11805 //Save the wep key in ap context. Issue setkey after the BSS is started.
11806 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11807 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
11808 }
11809 else
11810 {
11811 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011812 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011813 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
11814 }
11815 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011816 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
11817 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011818 {
11819 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11820 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11821
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011822#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11823 if (!pairwise)
11824#else
11825 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
11826#endif
11827 {
11828 /* set group key*/
11829 if (pHddStaCtx->roam_info.deferKeyComplete)
11830 {
11831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11832 "%s- %d: Perform Set key Complete",
11833 __func__, __LINE__);
11834 hdd_PerformRoamSetKeyComplete(pAdapter);
11835 }
11836 }
11837
Jeff Johnson295189b2012-06-20 16:38:30 -070011838 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
11839
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080011840 pWextState->roamProfile.Keys.defaultIndex = key_index;
11841
11842
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011843 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011844 params->key, params->key_len);
11845
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011846
Jeff Johnson295189b2012-06-20 16:38:30 -070011847 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11848
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011849 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011850 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011851 __func__, setKey.peerMac[0], setKey.peerMac[1],
11852 setKey.peerMac[2], setKey.peerMac[3],
11853 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011854 setKey.keyDirection);
11855
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011856 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053011857
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011858 if ( vos_status != VOS_STATUS_SUCCESS )
11859 {
11860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011861 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11862 __LINE__, vos_status );
11863
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011864 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011865
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011866 status = -EINVAL;
11867 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011868
11869 }
11870
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011871#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011872 /* The supplicant may attempt to set the PTK once pre-authentication
11873 is done. Save the key in the UMAC and include it in the ADD BSS
11874 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011875 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011876 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011877 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011878 hddLog(VOS_TRACE_LEVEL_INFO_MED,
11879 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011880 status = 0;
11881 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011882 }
11883 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
11884 {
11885 hddLog(VOS_TRACE_LEVEL_ERROR,
11886 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011887 status = -EINVAL;
11888 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011889 }
11890#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070011891
11892 /* issue set key request to SME*/
11893 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11894 pAdapter->sessionId, &setKey, &roamId );
11895
11896 if ( 0 != status )
11897 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011898 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011899 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
11900 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011901 status = -EINVAL;
11902 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011903 }
11904
11905
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011906 /* in case of IBSS as there was no information available about WEP keys during
11907 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070011908 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011909 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
11910 !( ( IW_AUTH_KEY_MGMT_802_1X
11911 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070011912 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
11913 )
11914 &&
11915 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
11916 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
11917 )
11918 )
11919 {
11920 setKey.keyDirection = eSIR_RX_ONLY;
11921 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11922
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011923 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011924 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011925 __func__, setKey.peerMac[0], setKey.peerMac[1],
11926 setKey.peerMac[2], setKey.peerMac[3],
11927 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011928 setKey.keyDirection);
11929
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011930 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011931 pAdapter->sessionId, &setKey, &roamId );
11932
11933 if ( 0 != status )
11934 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011935 hddLog(VOS_TRACE_LEVEL_ERROR,
11936 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011937 __func__, status);
11938 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011939 status = -EINVAL;
11940 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011941 }
11942 }
11943 }
11944
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011945end:
11946 /* Need to clear any trace of key value in the memory.
11947 * Thus zero out the memory even though it is local
11948 * variable.
11949 */
11950 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011951 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011952 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011953}
11954
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011955#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11956static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11957 struct net_device *ndev,
11958 u8 key_index, bool pairwise,
11959 const u8 *mac_addr,
11960 struct key_params *params
11961 )
11962#else
11963static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11964 struct net_device *ndev,
11965 u8 key_index, const u8 *mac_addr,
11966 struct key_params *params
11967 )
11968#endif
11969{
11970 int ret;
11971 vos_ssr_protect(__func__);
11972#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11973 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
11974 mac_addr, params);
11975#else
11976 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
11977 params);
11978#endif
11979 vos_ssr_unprotect(__func__);
11980
11981 return ret;
11982}
11983
Jeff Johnson295189b2012-06-20 16:38:30 -070011984/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011985 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011986 * This function is used to get the key information
11987 */
11988#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011989static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011990 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011991 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011992 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011993 const u8 *mac_addr, void *cookie,
11994 void (*callback)(void *cookie, struct key_params*)
11995 )
11996#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011997static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011998 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011999 struct net_device *ndev,
12000 u8 key_index, const u8 *mac_addr, void *cookie,
12001 void (*callback)(void *cookie, struct key_params*)
12002 )
12003#endif
12004{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012005 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012006 hdd_wext_state_t *pWextState = NULL;
12007 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012008 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012009 hdd_context_t *pHddCtx;
12010 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012011
12012 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012013
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012014 if (NULL == pAdapter)
12015 {
12016 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12017 "%s: HDD adapter is Null", __func__);
12018 return -ENODEV;
12019 }
12020
12021 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12022 ret = wlan_hdd_validate_context(pHddCtx);
12023 if (0 != ret)
12024 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012025 return ret;
12026 }
12027
12028 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12029 pRoamProfile = &(pWextState->roamProfile);
12030
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012031 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12032 __func__, hdd_device_modetoString(pAdapter->device_mode),
12033 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012034
Jeff Johnson295189b2012-06-20 16:38:30 -070012035 memset(&params, 0, sizeof(params));
12036
12037 if (CSR_MAX_NUM_KEY <= key_index)
12038 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012039 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012040 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012041 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012042
12043 switch(pRoamProfile->EncryptionType.encryptionType[0])
12044 {
12045 case eCSR_ENCRYPT_TYPE_NONE:
12046 params.cipher = IW_AUTH_CIPHER_NONE;
12047 break;
12048
12049 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
12050 case eCSR_ENCRYPT_TYPE_WEP40:
12051 params.cipher = WLAN_CIPHER_SUITE_WEP40;
12052 break;
12053
12054 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
12055 case eCSR_ENCRYPT_TYPE_WEP104:
12056 params.cipher = WLAN_CIPHER_SUITE_WEP104;
12057 break;
12058
12059 case eCSR_ENCRYPT_TYPE_TKIP:
12060 params.cipher = WLAN_CIPHER_SUITE_TKIP;
12061 break;
12062
12063 case eCSR_ENCRYPT_TYPE_AES:
12064 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
12065 break;
12066
12067 default:
12068 params.cipher = IW_AUTH_CIPHER_NONE;
12069 break;
12070 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012071
c_hpothuaaf19692014-05-17 17:01:48 +053012072 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12073 TRACE_CODE_HDD_CFG80211_GET_KEY,
12074 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012075
Jeff Johnson295189b2012-06-20 16:38:30 -070012076 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
12077 params.seq_len = 0;
12078 params.seq = NULL;
12079 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
12080 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012081 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012082 return 0;
12083}
12084
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012085#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12086static int wlan_hdd_cfg80211_get_key(
12087 struct wiphy *wiphy,
12088 struct net_device *ndev,
12089 u8 key_index, bool pairwise,
12090 const u8 *mac_addr, void *cookie,
12091 void (*callback)(void *cookie, struct key_params*)
12092 )
12093#else
12094static int wlan_hdd_cfg80211_get_key(
12095 struct wiphy *wiphy,
12096 struct net_device *ndev,
12097 u8 key_index, const u8 *mac_addr, void *cookie,
12098 void (*callback)(void *cookie, struct key_params*)
12099 )
12100#endif
12101{
12102 int ret;
12103
12104 vos_ssr_protect(__func__);
12105#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12106 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
12107 mac_addr, cookie, callback);
12108#else
12109 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
12110 callback);
12111#endif
12112 vos_ssr_unprotect(__func__);
12113
12114 return ret;
12115}
12116
Jeff Johnson295189b2012-06-20 16:38:30 -070012117/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012118 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012119 * This function is used to delete the key information
12120 */
12121#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012122static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012123 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012124 u8 key_index,
12125 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012126 const u8 *mac_addr
12127 )
12128#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012129static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012130 struct net_device *ndev,
12131 u8 key_index,
12132 const u8 *mac_addr
12133 )
12134#endif
12135{
12136 int status = 0;
12137
12138 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012139 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070012140 //it is observed that this is invalidating peer
12141 //key index whenever re-key is done. This is affecting data link.
12142 //It should be ok to ignore del_key.
12143#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012144 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
12145 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012146 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12147 tCsrRoamSetKey setKey;
12148 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012149
Jeff Johnson295189b2012-06-20 16:38:30 -070012150 ENTER();
12151
12152 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
12153 __func__,pAdapter->device_mode);
12154
12155 if (CSR_MAX_NUM_KEY <= key_index)
12156 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012157 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012158 key_index);
12159
12160 return -EINVAL;
12161 }
12162
12163 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12164 setKey.keyId = key_index;
12165
12166 if (mac_addr)
12167 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
12168 else
12169 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
12170
12171 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
12172
12173 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012174 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012175 )
12176 {
12177
12178 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070012179 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
12180 if( pHostapdState->bssState == BSS_START)
12181 {
12182 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012183
Jeff Johnson295189b2012-06-20 16:38:30 -070012184 if ( status != eHAL_STATUS_SUCCESS )
12185 {
12186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12187 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12188 __LINE__, status );
12189 }
12190 }
12191 }
12192 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012193 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070012194 )
12195 {
12196 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12197
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012198 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12199
12200 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012201 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012202 __func__, setKey.peerMac[0], setKey.peerMac[1],
12203 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070012204 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012205 if(pAdapter->sessionCtx.station.conn_info.connState ==
12206 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070012207 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012208 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012209 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012210
Jeff Johnson295189b2012-06-20 16:38:30 -070012211 if ( 0 != status )
12212 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012213 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012214 "%s: sme_RoamSetKey failure, returned %d",
12215 __func__, status);
12216 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12217 return -EINVAL;
12218 }
12219 }
12220 }
12221#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012222 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012223 return status;
12224}
12225
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012226#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12227static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12228 struct net_device *ndev,
12229 u8 key_index,
12230 bool pairwise,
12231 const u8 *mac_addr
12232 )
12233#else
12234static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12235 struct net_device *ndev,
12236 u8 key_index,
12237 const u8 *mac_addr
12238 )
12239#endif
12240{
12241 int ret;
12242
12243 vos_ssr_protect(__func__);
12244#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12245 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
12246 mac_addr);
12247#else
12248 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
12249#endif
12250 vos_ssr_unprotect(__func__);
12251
12252 return ret;
12253}
12254
Jeff Johnson295189b2012-06-20 16:38:30 -070012255/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012256 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012257 * This function is used to set the default tx key index
12258 */
12259#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012260static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012261 struct net_device *ndev,
12262 u8 key_index,
12263 bool unicast, bool multicast)
12264#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012265static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012266 struct net_device *ndev,
12267 u8 key_index)
12268#endif
12269{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012270 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012271 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012272 hdd_wext_state_t *pWextState;
12273 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012274 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012275
12276 ENTER();
12277
Gopichand Nakkala29149562013-05-10 21:43:41 +053012278 if ((NULL == pAdapter))
12279 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012281 "invalid adapter");
12282 return -EINVAL;
12283 }
12284
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012285 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12286 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
12287 pAdapter->sessionId, key_index));
12288
Gopichand Nakkala29149562013-05-10 21:43:41 +053012289 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12290 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12291
12292 if ((NULL == pWextState) || (NULL == pHddStaCtx))
12293 {
12294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12295 "invalid Wext state or HDD context");
12296 return -EINVAL;
12297 }
12298
Arif Hussain6d2a3322013-11-17 19:50:10 -080012299 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012300 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012301
Jeff Johnson295189b2012-06-20 16:38:30 -070012302 if (CSR_MAX_NUM_KEY <= key_index)
12303 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012304 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012305 key_index);
12306
12307 return -EINVAL;
12308 }
12309
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012310 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12311 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012312 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012313 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012314 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012315 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012316
Jeff Johnson295189b2012-06-20 16:38:30 -070012317 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012318 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012319 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012320 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012321 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080012322 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012323 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080012324 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070012325 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012326 {
12327 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070012328 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012329
Jeff Johnson295189b2012-06-20 16:38:30 -070012330 tCsrRoamSetKey setKey;
12331 v_U32_t roamId= 0xFF;
12332 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012333
12334 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012335 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012336
Jeff Johnson295189b2012-06-20 16:38:30 -070012337 Keys->defaultIndex = (u8)key_index;
12338 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12339 setKey.keyId = key_index;
12340 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012341
12342 vos_mem_copy(&setKey.Key[0],
12343 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012344 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012345
Gopichand Nakkala29149562013-05-10 21:43:41 +053012346 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012347
12348 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070012349 &pHddStaCtx->conn_info.bssId[0],
12350 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012351
Gopichand Nakkala29149562013-05-10 21:43:41 +053012352 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
12353 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
12354 eCSR_ENCRYPT_TYPE_WEP104)
12355 {
12356 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
12357 even though ap is configured for WEP-40 encryption. In this canse the key length
12358 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
12359 type(104) and switching encryption type to 40*/
12360 pWextState->roamProfile.EncryptionType.encryptionType[0] =
12361 eCSR_ENCRYPT_TYPE_WEP40;
12362 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
12363 eCSR_ENCRYPT_TYPE_WEP40;
12364 }
12365
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012366 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012367 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012368
Jeff Johnson295189b2012-06-20 16:38:30 -070012369 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012370 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012371 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012372
Jeff Johnson295189b2012-06-20 16:38:30 -070012373 if ( 0 != status )
12374 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012375 hddLog(VOS_TRACE_LEVEL_ERROR,
12376 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012377 status);
12378 return -EINVAL;
12379 }
12380 }
12381 }
12382
12383 /* In SoftAp mode setting key direction for default mode */
12384 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
12385 {
12386 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
12387 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
12388 (eCSR_ENCRYPT_TYPE_AES !=
12389 pWextState->roamProfile.EncryptionType.encryptionType[0])
12390 )
12391 {
12392 /* Saving key direction for default key index to TX default */
12393 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12394 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
12395 }
12396 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012397 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012398 return status;
12399}
12400
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012401#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12402static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12403 struct net_device *ndev,
12404 u8 key_index,
12405 bool unicast, bool multicast)
12406#else
12407static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12408 struct net_device *ndev,
12409 u8 key_index)
12410#endif
12411{
12412 int ret;
12413 vos_ssr_protect(__func__);
12414#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12415 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
12416 multicast);
12417#else
12418 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
12419#endif
12420 vos_ssr_unprotect(__func__);
12421
12422 return ret;
12423}
12424
Jeff Johnson295189b2012-06-20 16:38:30 -070012425/*
12426 * FUNCTION: wlan_hdd_cfg80211_inform_bss
12427 * This function is used to inform the BSS details to nl80211 interface.
12428 */
12429static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
12430 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
12431{
12432 struct net_device *dev = pAdapter->dev;
12433 struct wireless_dev *wdev = dev->ieee80211_ptr;
12434 struct wiphy *wiphy = wdev->wiphy;
12435 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12436 int chan_no;
12437 int ie_length;
12438 const char *ie;
12439 unsigned int freq;
12440 struct ieee80211_channel *chan;
12441 int rssi = 0;
12442 struct cfg80211_bss *bss = NULL;
12443
Jeff Johnson295189b2012-06-20 16:38:30 -070012444 if( NULL == pBssDesc )
12445 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012446 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012447 return bss;
12448 }
12449
12450 chan_no = pBssDesc->channelId;
12451 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12452 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12453
12454 if( NULL == ie )
12455 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012456 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012457 return bss;
12458 }
12459
12460#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12461 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12462 {
12463 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12464 }
12465 else
12466 {
12467 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12468 }
12469#else
12470 freq = ieee80211_channel_to_frequency(chan_no);
12471#endif
12472
12473 chan = __ieee80211_get_channel(wiphy, freq);
12474
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012475 if (!chan) {
12476 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12477 return NULL;
12478 }
12479
Abhishek Singhaee43942014-06-16 18:55:47 +053012480 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012481
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012482 return cfg80211_inform_bss(wiphy, chan,
12483#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12484 CFG80211_BSS_FTYPE_UNKNOWN,
12485#endif
12486 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012487 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012488 pBssDesc->capabilityInfo,
12489 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012490 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012491}
12492
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012493/*
12494 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
12495 * interface that BSS might have been lost.
12496 * @pAdapter: adaptor
12497 * @bssid: bssid which might have been lost
12498 *
12499 * Return: bss which is unlinked from kernel cache
12500 */
12501struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
12502 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
12503{
12504 struct net_device *dev = pAdapter->dev;
12505 struct wireless_dev *wdev = dev->ieee80211_ptr;
12506 struct wiphy *wiphy = wdev->wiphy;
12507 struct cfg80211_bss *bss = NULL;
12508
Abhishek Singh5a597e62016-12-05 15:16:30 +053012509 bss = hdd_get_bss_entry(wiphy,
12510 NULL, bssid,
12511 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012512 if (bss == NULL) {
12513 hddLog(LOGE, FL("BSS not present"));
12514 } else {
12515 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
12516 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
12517 cfg80211_unlink_bss(wiphy, bss);
12518 }
12519 return bss;
12520}
Jeff Johnson295189b2012-06-20 16:38:30 -070012521
12522
12523/*
12524 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12525 * This function is used to inform the BSS details to nl80211 interface.
12526 */
12527struct cfg80211_bss*
12528wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
12529 tSirBssDescription *bss_desc
12530 )
12531{
12532 /*
12533 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
12534 already exists in bss data base of cfg80211 for that particular BSS ID.
12535 Using cfg80211_inform_bss_frame to update the bss entry instead of
12536 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
12537 now there is no possibility to get the mgmt(probe response) frame from PE,
12538 converting bss_desc to ieee80211_mgmt(probe response) and passing to
12539 cfg80211_inform_bss_frame.
12540 */
12541 struct net_device *dev = pAdapter->dev;
12542 struct wireless_dev *wdev = dev->ieee80211_ptr;
12543 struct wiphy *wiphy = wdev->wiphy;
12544 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012545#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12546 qcom_ie_age *qie_age = NULL;
12547 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12548#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012549 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012550#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012551 const char *ie =
12552 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12553 unsigned int freq;
12554 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012555 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012556 struct cfg80211_bss *bss_status = NULL;
12557 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
12558 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070012559 hdd_context_t *pHddCtx;
12560 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070012561#ifdef WLAN_OPEN_SOURCE
12562 struct timespec ts;
12563#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012564
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012565
Wilson Yangf80a0542013-10-07 13:02:37 -070012566 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12567 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070012568 if (0 != status)
12569 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012570 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012571 }
12572
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012573 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070012574 if (!mgmt)
12575 {
12576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12577 "%s: memory allocation failed ", __func__);
12578 return NULL;
12579 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012580
Jeff Johnson295189b2012-06-20 16:38:30 -070012581 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012582
12583#ifdef WLAN_OPEN_SOURCE
12584 /* Android does not want the timestamp from the frame.
12585 Instead it wants a monotonic increasing value */
12586 get_monotonic_boottime(&ts);
12587 mgmt->u.probe_resp.timestamp =
12588 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
12589#else
12590 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012591 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
12592 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070012593
12594#endif
12595
Jeff Johnson295189b2012-06-20 16:38:30 -070012596 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
12597 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012598
12599#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12600 /* GPS Requirement: need age ie per entry. Using vendor specific. */
12601 /* Assuming this is the last IE, copy at the end */
12602 ie_length -=sizeof(qcom_ie_age);
12603 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
12604 qie_age->element_id = QCOM_VENDOR_IE_ID;
12605 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
12606 qie_age->oui_1 = QCOM_OUI1;
12607 qie_age->oui_2 = QCOM_OUI2;
12608 qie_age->oui_3 = QCOM_OUI3;
12609 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053012610 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
12611 * bss related timestamp is in units of ms. Due to this when scan results
12612 * are sent to lowi the scan age is high.To address this, send age in units
12613 * of 1/10 ms.
12614 */
12615 qie_age->age = (vos_timer_get_system_time() -
12616 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012617#endif
12618
Jeff Johnson295189b2012-06-20 16:38:30 -070012619 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053012620 if (bss_desc->fProbeRsp)
12621 {
12622 mgmt->frame_control |=
12623 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
12624 }
12625 else
12626 {
12627 mgmt->frame_control |=
12628 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
12629 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012630
12631#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012632 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012633 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
12634 {
12635 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12636 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012637 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012638 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
12639
12640 {
12641 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12642 }
12643 else
12644 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012645 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
12646 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070012647 kfree(mgmt);
12648 return NULL;
12649 }
12650#else
12651 freq = ieee80211_channel_to_frequency(chan_no);
12652#endif
12653 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012654 /*when the band is changed on the fly using the GUI, three things are done
12655 * 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)
12656 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
12657 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
12658 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
12659 * and discards the channels correponding to previous band and calls back with zero bss results.
12660 * 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
12661 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
12662 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
12663 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
12664 * So drop the bss and continue to next bss.
12665 */
12666 if(chan == NULL)
12667 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053012668 hddLog(VOS_TRACE_LEVEL_ERROR,
12669 FL("chan pointer is NULL, chan_no: %d freq: %d"),
12670 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070012671 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012672 return NULL;
12673 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053012674 /*To keep the rssi icon of the connected AP in the scan window
12675 *and the rssi icon of the wireless networks in sync
12676 * */
12677 if (( eConnectionState_Associated ==
12678 pAdapter->sessionCtx.station.conn_info.connState ) &&
12679 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
12680 pAdapter->sessionCtx.station.conn_info.bssId,
12681 WNI_CFG_BSSID_LEN)) &&
12682 (pHddCtx->hdd_wlan_suspended == FALSE))
12683 {
12684 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
12685 rssi = (pAdapter->rssi * 100);
12686 }
12687 else
12688 {
12689 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
12690 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012691
Nirav Shah20ac06f2013-12-12 18:14:06 +053012692 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053012693 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
12694 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053012695
Jeff Johnson295189b2012-06-20 16:38:30 -070012696 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
12697 frame_len, rssi, GFP_KERNEL);
12698 kfree(mgmt);
12699 return bss_status;
12700}
12701
12702/*
12703 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
12704 * This function is used to update the BSS data base of CFG8011
12705 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012706struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012707 tCsrRoamInfo *pRoamInfo
12708 )
12709{
12710 tCsrRoamConnectedProfile roamProfile;
12711 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12712 struct cfg80211_bss *bss = NULL;
12713
12714 ENTER();
12715
12716 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
12717 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
12718
12719 if (NULL != roamProfile.pBssDesc)
12720 {
Girish Gowlif4b68022014-08-28 23:18:57 +053012721 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12722 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070012723
12724 if (NULL == bss)
12725 {
12726 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
12727 __func__);
12728 }
12729
12730 sme_RoamFreeConnectProfile(hHal, &roamProfile);
12731 }
12732 else
12733 {
12734 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
12735 __func__);
12736 }
12737 return bss;
12738}
12739
12740/*
12741 * FUNCTION: wlan_hdd_cfg80211_update_bss
12742 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012743static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
12744 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070012745 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012746{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012747 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012748 tCsrScanResultInfo *pScanResult;
12749 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012750 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012751 tScanResultHandle pResult;
12752 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012753 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012754 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012755 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012756
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012757 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12758 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
12759 NO_SESSION, pAdapter->sessionId));
12760
Wilson Yangf80a0542013-10-07 13:02:37 -070012761 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012762 ret = wlan_hdd_validate_context(pHddCtx);
12763 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070012764 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012765 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070012766 }
12767
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012768 if (pAdapter->request != NULL)
12769 {
12770 if ((pAdapter->request->n_ssids == 1)
12771 && (pAdapter->request->ssids != NULL)
12772 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
12773 is_p2p_scan = true;
12774 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012775 /*
12776 * start getting scan results and populate cgf80211 BSS database
12777 */
12778 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
12779
12780 /* no scan results */
12781 if (NULL == pResult)
12782 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012783 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
12784 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012785 wlan_hdd_get_frame_logs(pAdapter,
12786 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070012787 return status;
12788 }
12789
12790 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
12791
12792 while (pScanResult)
12793 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012794 /*
12795 * cfg80211_inform_bss() is not updating ie field of bss entry, if
12796 * entry already exists in bss data base of cfg80211 for that
12797 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
12798 * bss entry instead of cfg80211_inform_bss, But this call expects
12799 * mgmt packet as input. As of now there is no possibility to get
12800 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070012801 * ieee80211_mgmt(probe response) and passing to c
12802 * fg80211_inform_bss_frame.
12803 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012804 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
12805 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
12806 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012807 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12808 continue; //Skip the non p2p bss entries
12809 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012810 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12811 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012812
Jeff Johnson295189b2012-06-20 16:38:30 -070012813
12814 if (NULL == bss_status)
12815 {
12816 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012817 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012818 }
12819 else
12820 {
Yue Maf49ba872013-08-19 12:04:25 -070012821 cfg80211_put_bss(
12822#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
12823 wiphy,
12824#endif
12825 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012826 }
12827
12828 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12829 }
12830
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012831 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012832 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012833 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012834}
12835
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012836void
12837hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
12838{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012839 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080012840 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012841} /****** end hddPrintMacAddr() ******/
12842
12843void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012844hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012845{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012846 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012847 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012848 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
12849 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
12850 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012851} /****** end hddPrintPmkId() ******/
12852
12853//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
12854//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
12855
12856//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
12857//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
12858
12859#define dump_bssid(bssid) \
12860 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012861 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
12862 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012863 }
12864
12865#define dump_pmkid(pMac, pmkid) \
12866 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012867 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
12868 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012869 }
12870
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070012871#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012872/*
12873 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
12874 * This function is used to notify the supplicant of a new PMKSA candidate.
12875 */
12876int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012877 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012878 int index, bool preauth )
12879{
Jeff Johnsone7245742012-09-05 17:12:55 -070012880#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012881 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012882 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012883
12884 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070012885 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012886
12887 if( NULL == pRoamInfo )
12888 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012889 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012890 return -EINVAL;
12891 }
12892
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012893 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
12894 {
12895 dump_bssid(pRoamInfo->bssid);
12896 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012897 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012898 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012899#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012900 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012901}
12902#endif //FEATURE_WLAN_LFR
12903
Yue Maef608272013-04-08 23:09:17 -070012904#ifdef FEATURE_WLAN_LFR_METRICS
12905/*
12906 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
12907 * 802.11r/LFR metrics reporting function to report preauth initiation
12908 *
12909 */
12910#define MAX_LFR_METRICS_EVENT_LENGTH 100
12911VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
12912 tCsrRoamInfo *pRoamInfo)
12913{
12914 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12915 union iwreq_data wrqu;
12916
12917 ENTER();
12918
12919 if (NULL == pAdapter)
12920 {
12921 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12922 return VOS_STATUS_E_FAILURE;
12923 }
12924
12925 /* create the event */
12926 memset(&wrqu, 0, sizeof(wrqu));
12927 memset(metrics_notification, 0, sizeof(metrics_notification));
12928
12929 wrqu.data.pointer = metrics_notification;
12930 wrqu.data.length = scnprintf(metrics_notification,
12931 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
12932 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12933
12934 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12935
12936 EXIT();
12937
12938 return VOS_STATUS_SUCCESS;
12939}
12940
12941/*
12942 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
12943 * 802.11r/LFR metrics reporting function to report preauth completion
12944 * or failure
12945 */
12946VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
12947 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
12948{
12949 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12950 union iwreq_data wrqu;
12951
12952 ENTER();
12953
12954 if (NULL == pAdapter)
12955 {
12956 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12957 return VOS_STATUS_E_FAILURE;
12958 }
12959
12960 /* create the event */
12961 memset(&wrqu, 0, sizeof(wrqu));
12962 memset(metrics_notification, 0, sizeof(metrics_notification));
12963
12964 scnprintf(metrics_notification, sizeof(metrics_notification),
12965 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
12966 MAC_ADDR_ARRAY(pRoamInfo->bssid));
12967
12968 if (1 == preauth_status)
12969 strncat(metrics_notification, " TRUE", 5);
12970 else
12971 strncat(metrics_notification, " FALSE", 6);
12972
12973 wrqu.data.pointer = metrics_notification;
12974 wrqu.data.length = strlen(metrics_notification);
12975
12976 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12977
12978 EXIT();
12979
12980 return VOS_STATUS_SUCCESS;
12981}
12982
12983/*
12984 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
12985 * 802.11r/LFR metrics reporting function to report handover initiation
12986 *
12987 */
12988VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
12989 tCsrRoamInfo *pRoamInfo)
12990{
12991 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12992 union iwreq_data wrqu;
12993
12994 ENTER();
12995
12996 if (NULL == pAdapter)
12997 {
12998 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12999 return VOS_STATUS_E_FAILURE;
13000 }
13001
13002 /* create the event */
13003 memset(&wrqu, 0, sizeof(wrqu));
13004 memset(metrics_notification, 0, sizeof(metrics_notification));
13005
13006 wrqu.data.pointer = metrics_notification;
13007 wrqu.data.length = scnprintf(metrics_notification,
13008 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
13009 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13010
13011 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13012
13013 EXIT();
13014
13015 return VOS_STATUS_SUCCESS;
13016}
13017#endif
13018
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013019
13020/**
13021 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
13022 * @scan_req: scan request to be checked
13023 *
13024 * Return: true or false
13025 */
13026#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
13027static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13028 cfg80211_scan_request
13029 *scan_req)
13030{
13031 if (!scan_req || !scan_req->wiphy) {
13032 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13033 return false;
13034 }
13035 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
13036 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
13037 return false;
13038 }
13039 return true;
13040}
13041#else
13042static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13043 cfg80211_scan_request
13044 *scan_req)
13045{
13046 if (!scan_req || !scan_req->wiphy) {
13047 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13048 return false;
13049 }
13050 return true;
13051}
13052#endif
13053
13054
Jeff Johnson295189b2012-06-20 16:38:30 -070013055/*
13056 * FUNCTION: hdd_cfg80211_scan_done_callback
13057 * scanning callback function, called after finishing scan
13058 *
13059 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013060static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070013061 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
13062{
13063 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013064 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013065 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013066 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013067 struct cfg80211_scan_request *req = NULL;
13068 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013069 bool aborted = false;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013070#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13071 bool iface_down = false;
13072#endif
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013073 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013074 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013075 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013076
13077 ENTER();
13078
c_manjee1b4ab9a2016-10-26 11:36:55 +053013079 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
13080 !pAdapter->dev) {
13081 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
13082 return 0;
13083 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013084 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053013085 if (NULL == pHddCtx) {
13086 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013087 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013088 }
13089
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013090#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13091 if (!(pAdapter->dev->flags & IFF_UP))
13092 {
13093 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013094 iface_down = true;
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013095 }
13096#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013097 pScanInfo = &pHddCtx->scan_info;
13098
Jeff Johnson295189b2012-06-20 16:38:30 -070013099 hddLog(VOS_TRACE_LEVEL_INFO,
13100 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080013101 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013102 __func__, halHandle, pContext, (int) scanId, (int) status);
13103
Kiet Lamac06e2c2013-10-23 16:25:07 +053013104 pScanInfo->mScanPendingCounter = 0;
13105
Jeff Johnson295189b2012-06-20 16:38:30 -070013106 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013107 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070013108 &pScanInfo->scan_req_completion_event,
13109 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013110 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070013111 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013112 hddLog(VOS_TRACE_LEVEL_ERROR,
13113 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070013114 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013115 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013116 }
13117
Yue Maef608272013-04-08 23:09:17 -070013118 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070013119 {
13120 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013121 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013122 }
13123
13124 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013125 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070013126 {
13127 hddLog(VOS_TRACE_LEVEL_INFO,
13128 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080013129 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070013130 (int) scanId);
13131 }
13132
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013133#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013134 if (!iface_down)
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013135#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013136 {
13137 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
13138 pAdapter);
13139 if (0 > ret)
13140 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013141 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013142
Jeff Johnson295189b2012-06-20 16:38:30 -070013143 /* If any client wait scan result through WEXT
13144 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013145 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070013146 {
13147 /* The other scan request waiting for current scan finish
13148 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013149 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013150 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013151 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070013152 }
13153 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013154 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013155 {
13156 struct net_device *dev = pAdapter->dev;
13157 union iwreq_data wrqu;
13158 int we_event;
13159 char *msg;
13160
13161 memset(&wrqu, '\0', sizeof(wrqu));
13162 we_event = SIOCGIWSCAN;
13163 msg = NULL;
13164 wireless_send_event(dev, we_event, &wrqu, msg);
13165 }
13166 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013167 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013168
13169 /* Get the Scan Req */
13170 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053013171 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013172
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013173 /* Scan is no longer pending */
13174 pScanInfo->mScanPending = VOS_FALSE;
13175
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013176 if (!wlan_hdd_cfg80211_validate_scan_req(req))
Jeff Johnson295189b2012-06-20 16:38:30 -070013177 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013178#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13179 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
13180 iface_down ? "up" : "down");
13181#endif
13182
13183 if (pAdapter->dev) {
13184 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
13185 pAdapter->dev->name);
13186 }
mukul sharmae7041822015-12-03 15:09:21 +053013187 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070013188 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013189 }
13190
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013191 /* last_scan_timestamp is used to decide if new scan
13192 * is needed or not on station interface. If last station
13193 * scan time and new station scan time is less then
13194 * last_scan_timestamp ; driver will return cached scan.
13195 */
13196 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
13197 {
13198 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
13199
13200 if ( req->n_channels )
13201 {
13202 for (i = 0; i < req->n_channels ; i++ )
13203 {
13204 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
13205 }
13206 /* store no of channel scanned */
13207 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
13208 }
13209
13210 }
13211
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070013212 /*
13213 * cfg80211_scan_done informing NL80211 about completion
13214 * of scanning
13215 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013216 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
13217 {
13218 aborted = true;
13219 }
mukul sharmae7041822015-12-03 15:09:21 +053013220
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013221#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13222 if (!iface_down)
13223#endif
13224 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053013225
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013226 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070013227
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013228allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013229 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
13230 ) && (pHddCtx->spoofMacAddr.isEnabled
13231 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053013232 /* Generate new random mac addr for next scan */
13233 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053013234
13235 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
13236 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053013237 }
13238
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013239 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013240 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013241
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013242 /* Acquire wakelock to handle the case where APP's tries to suspend
13243 * immediatly after the driver gets connect request(i.e after scan)
13244 * from supplicant, this result in app's is suspending and not able
13245 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013246 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013247
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013248#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13249 if (!iface_down)
13250#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013251#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013252 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013253#endif
13254
Jeff Johnson295189b2012-06-20 16:38:30 -070013255 EXIT();
13256 return 0;
13257}
13258
13259/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053013260 * FUNCTION: hdd_isConnectionInProgress
13261 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013262 *
13263 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013264v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
13265 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013266{
13267 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13268 hdd_station_ctx_t *pHddStaCtx = NULL;
13269 hdd_adapter_t *pAdapter = NULL;
13270 VOS_STATUS status = 0;
13271 v_U8_t staId = 0;
13272 v_U8_t *staMac = NULL;
13273
13274 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13275
13276 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13277 {
13278 pAdapter = pAdapterNode->pAdapter;
13279
13280 if( pAdapter )
13281 {
13282 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013283 "%s: Adapter with device mode %s (%d) exists",
13284 __func__, hdd_device_modetoString(pAdapter->device_mode),
13285 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013286 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053013287 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13288 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
13289 (eConnectionState_Connecting ==
13290 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13291 {
13292 hddLog(VOS_TRACE_LEVEL_ERROR,
13293 "%s: %p(%d) Connection is in progress", __func__,
13294 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013295 if (session_id && reason)
13296 {
13297 *session_id = pAdapter->sessionId;
13298 *reason = eHDD_CONNECTION_IN_PROGRESS;
13299 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013300 return VOS_TRUE;
13301 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013302 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053013303 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013304 {
13305 hddLog(VOS_TRACE_LEVEL_ERROR,
13306 "%s: %p(%d) Reassociation is in progress", __func__,
13307 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013308 if (session_id && reason)
13309 {
13310 *session_id = pAdapter->sessionId;
13311 *reason = eHDD_REASSOC_IN_PROGRESS;
13312 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013313 return VOS_TRUE;
13314 }
13315 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013316 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13317 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013318 {
13319 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13320 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013321 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013322 {
13323 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
13324 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013325 "%s: client " MAC_ADDRESS_STR
13326 " is in the middle of WPS/EAPOL exchange.", __func__,
13327 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013328 if (session_id && reason)
13329 {
13330 *session_id = pAdapter->sessionId;
13331 *reason = eHDD_EAPOL_IN_PROGRESS;
13332 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013333 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013334 }
13335 }
13336 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
13337 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
13338 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013339 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13340 ptSapContext pSapCtx = NULL;
13341 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13342 if(pSapCtx == NULL){
13343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13344 FL("psapCtx is NULL"));
13345 return VOS_FALSE;
13346 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013347 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
13348 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013349 if ((pSapCtx->aStaInfo[staId].isUsed) &&
13350 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013351 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013352 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013353
13354 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013355 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
13356 "middle of WPS/EAPOL exchange.", __func__,
13357 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013358 if (session_id && reason)
13359 {
13360 *session_id = pAdapter->sessionId;
13361 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
13362 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013363 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013364 }
13365 }
13366 }
13367 }
13368 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13369 pAdapterNode = pNext;
13370 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013371 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013372}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013373
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013374/**
13375 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
13376 * to the Scan request
13377 * @scanRequest: Pointer to the csr scan request
13378 * @request: Pointer to the scan request from supplicant
13379 *
13380 * Return: None
13381 */
13382#ifdef CFG80211_SCAN_BSSID
13383static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13384 struct cfg80211_scan_request *request)
13385{
13386 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
13387}
13388#else
13389static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13390 struct cfg80211_scan_request *request)
13391{
13392}
13393#endif
13394
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013395/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013396 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070013397 * this scan respond to scan trigger and update cfg80211 scan database
13398 * later, scan dump command can be used to recieve scan results
13399 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013400int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013401#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13402 struct net_device *dev,
13403#endif
13404 struct cfg80211_scan_request *request)
13405{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013406 hdd_adapter_t *pAdapter = NULL;
13407 hdd_context_t *pHddCtx = NULL;
13408 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013409 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013410 tCsrScanRequest scanRequest;
13411 tANI_U8 *channelList = NULL, i;
13412 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013413 int status;
13414 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013415 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013416 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053013417 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013418 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013419 v_U8_t curr_session_id;
13420 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070013421
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013422#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
13423 struct net_device *dev = NULL;
13424 if (NULL == request)
13425 {
13426 hddLog(VOS_TRACE_LEVEL_ERROR,
13427 "%s: scan req param null", __func__);
13428 return -EINVAL;
13429 }
13430 dev = request->wdev->netdev;
13431#endif
13432
13433 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13434 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
13435 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13436
Jeff Johnson295189b2012-06-20 16:38:30 -070013437 ENTER();
13438
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013439 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13440 __func__, hdd_device_modetoString(pAdapter->device_mode),
13441 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013442
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013443 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013444 if (0 != status)
13445 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013446 return status;
13447 }
13448
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013449 if (NULL == pwextBuf)
13450 {
13451 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
13452 __func__);
13453 return -EIO;
13454 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013455 cfg_param = pHddCtx->cfg_ini;
13456 pScanInfo = &pHddCtx->scan_info;
13457
Jeff Johnson295189b2012-06-20 16:38:30 -070013458#ifdef WLAN_BTAMP_FEATURE
13459 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013460 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070013461 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013462 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013463 "%s: No scanning when AMP is on", __func__);
13464 return -EOPNOTSUPP;
13465 }
13466#endif
13467 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013468 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013469 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013470 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013471 "%s: Not scanning on device_mode = %s (%d)",
13472 __func__, hdd_device_modetoString(pAdapter->device_mode),
13473 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013474 return -EOPNOTSUPP;
13475 }
13476
13477 if (TRUE == pScanInfo->mScanPending)
13478 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013479 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
13480 {
13481 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
13482 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013483 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013484 }
13485
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053013486 // Don't allow scan if PNO scan is going on.
13487 if (pHddCtx->isPnoEnable)
13488 {
13489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13490 FL("pno scan in progress"));
13491 return -EBUSY;
13492 }
13493
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013494 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070013495 //Channel and action frame is pending
13496 //Otherwise Cancel Remain On Channel and allow Scan
13497 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013498 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070013499 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013500 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070013501 return -EBUSY;
13502 }
13503
Jeff Johnson295189b2012-06-20 16:38:30 -070013504 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
13505 {
13506 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080013507 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013508 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013509 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013510 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
13511 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013512 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013513 "%s: MAX TM Level Scan not allowed", __func__);
13514 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013515 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013516 }
13517 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
13518
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013519 /* Check if scan is allowed at this point of time.
13520 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053013521 if (TRUE == pHddCtx->btCoexModeSet)
13522 {
13523 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13524 FL("BTCoex Mode operation in progress"));
13525 return -EBUSY;
13526 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013527 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013528 {
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013529 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Scan not allowed"));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013530 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
13531 pHddCtx->last_scan_reject_reason != curr_reason ||
13532 !pHddCtx->last_scan_reject_timestamp)
13533 {
13534 pHddCtx->last_scan_reject_session_id = curr_session_id;
13535 pHddCtx->last_scan_reject_reason = curr_reason;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053013536 pHddCtx->last_scan_reject_timestamp = jiffies_to_msecs(jiffies);
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013537 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013538 else {
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053013539 if ((jiffies_to_msecs(jiffies) -
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013540 pHddCtx->last_scan_reject_timestamp) >=
13541 SCAN_REJECT_THRESHOLD_TIME)
13542 {
13543 pHddCtx->last_scan_reject_timestamp = 0;
13544 if (pHddCtx->cfg_ini->enableFatalEvent)
13545 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
13546 WLAN_LOG_INDICATOR_HOST_DRIVER,
13547 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
13548 FALSE, FALSE);
13549 else
13550 {
13551 hddLog(LOGE, FL("Triggering SSR"));
13552 vos_wlanRestart();
13553 }
13554 }
13555 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013556 return -EBUSY;
13557 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013558 pHddCtx->last_scan_reject_timestamp = 0;
13559 pHddCtx->last_scan_reject_session_id = 0xFF;
13560 pHddCtx->last_scan_reject_reason = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013561
Jeff Johnson295189b2012-06-20 16:38:30 -070013562 vos_mem_zero( &scanRequest, sizeof(scanRequest));
13563
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013564 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
13565 * Becasue of this, driver is assuming that this is not wildcard scan and so
13566 * is not aging out the scan results.
13567 */
13568 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070013569 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013570 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013571 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013572
13573 if ((request->ssids) && (0 < request->n_ssids))
13574 {
13575 tCsrSSIDInfo *SsidInfo;
13576 int j;
13577 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
13578 /* Allocate num_ssid tCsrSSIDInfo structure */
13579 SsidInfo = scanRequest.SSIDs.SSIDList =
13580 ( tCsrSSIDInfo *)vos_mem_malloc(
13581 request->n_ssids*sizeof(tCsrSSIDInfo));
13582
13583 if(NULL == scanRequest.SSIDs.SSIDList)
13584 {
13585 hddLog(VOS_TRACE_LEVEL_ERROR,
13586 "%s: memory alloc failed SSIDInfo buffer", __func__);
13587 return -ENOMEM;
13588 }
13589
13590 /* copy all the ssid's and their length */
13591 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
13592 {
13593 /* get the ssid length */
13594 SsidInfo->SSID.length = request->ssids[j].ssid_len;
13595 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
13596 SsidInfo->SSID.length);
13597 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
13598 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
13599 j, SsidInfo->SSID.ssId);
13600 }
13601 /* set the scan type to active */
13602 scanRequest.scanType = eSIR_ACTIVE_SCAN;
13603 }
13604 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013605 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013606 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13607 TRACE_CODE_HDD_CFG80211_SCAN,
13608 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070013609 /* set the scan type to active */
13610 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070013611 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013612 else
13613 {
13614 /*Set the scan type to default type, in this case it is ACTIVE*/
13615 scanRequest.scanType = pScanInfo->scan_mode;
13616 }
13617 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
13618 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070013619
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013620 csr_scan_request_assign_bssid(&scanRequest, request);
13621
Jeff Johnson295189b2012-06-20 16:38:30 -070013622 /* set BSSType to default type */
13623 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
13624
13625 /*TODO: scan the requested channels only*/
13626
13627 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013628 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070013629 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013630 hddLog(VOS_TRACE_LEVEL_WARN,
13631 "No of Scan Channels exceeded limit: %d", request->n_channels);
13632 request->n_channels = MAX_CHANNEL;
13633 }
13634
13635 hddLog(VOS_TRACE_LEVEL_INFO,
13636 "No of Scan Channels: %d", request->n_channels);
13637
13638
13639 if( request->n_channels )
13640 {
13641 char chList [(request->n_channels*5)+1];
13642 int len;
13643 channelList = vos_mem_malloc( request->n_channels );
13644 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053013645 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013646 hddLog(VOS_TRACE_LEVEL_ERROR,
13647 "%s: memory alloc failed channelList", __func__);
13648 status = -ENOMEM;
13649 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053013650 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013651
13652 for( i = 0, len = 0; i < request->n_channels ; i++ )
13653 {
13654 channelList[i] = request->channels[i]->hw_value;
13655 len += snprintf(chList+len, 5, "%d ", channelList[i]);
13656 }
13657
Nirav Shah20ac06f2013-12-12 18:14:06 +053013658 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013659 "Channel-List: %s ", chList);
13660 }
c_hpothu53512302014-04-15 18:49:53 +053013661
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013662 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
13663 scanRequest.ChannelInfo.ChannelList = channelList;
13664
13665 /* set requestType to full scan */
13666 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
13667
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013668 /* if there is back to back scan happening in driver with in
13669 * nDeferScanTimeInterval interval driver should defer new scan request
13670 * and should provide last cached scan results instead of new channel list.
13671 * This rule is not applicable if scan is p2p scan.
13672 * This condition will work only in case when last request no of channels
13673 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053013674 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053013675 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013676 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013677
Sushant Kaushik86592172015-04-27 16:35:03 +053013678 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
13679 /* if wps ie is NULL , then only defer scan */
13680 if ( pWpsIe == NULL &&
13681 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053013682 {
13683 if ( pScanInfo->last_scan_timestamp !=0 &&
13684 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
13685 {
13686 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
13687 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
13688 vos_mem_compare(pScanInfo->last_scan_channelList,
13689 channelList, pScanInfo->last_scan_numChannels))
13690 {
13691 hddLog(VOS_TRACE_LEVEL_WARN,
13692 " New and old station scan time differ is less then %u",
13693 pHddCtx->cfg_ini->nDeferScanTimeInterval);
13694
13695 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013696 pAdapter);
13697
Agarwal Ashish57e84372014-12-05 18:26:53 +053013698 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013699 "Return old cached scan as all channels and no of channels are same");
13700
Agarwal Ashish57e84372014-12-05 18:26:53 +053013701 if (0 > ret)
13702 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013703
Agarwal Ashish57e84372014-12-05 18:26:53 +053013704 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013705
13706 status = eHAL_STATUS_SUCCESS;
13707 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053013708 }
13709 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013710 }
13711
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013712 /* Flush the scan results(only p2p beacons) for STA scan and P2P
13713 * search (Flush on both full scan and social scan but not on single
13714 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
13715 */
13716
13717 /* Supplicant does single channel scan after 8-way handshake
13718 * and in that case driver shoudnt flush scan results. If
13719 * driver flushes the scan results here and unfortunately if
13720 * the AP doesnt respond to our probe req then association
13721 * fails which is not desired
13722 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013723 if ((request->n_ssids == 1)
13724 && (request->ssids != NULL)
13725 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13726 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013727
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013728 if( is_p2p_scan ||
13729 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013730 {
13731 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13732 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13733 pAdapter->sessionId );
13734 }
13735
13736 if( request->ie_len )
13737 {
13738 /* save this for future association (join requires this) */
13739 /*TODO: Array needs to be converted to dynamic allocation,
13740 * as multiple ie.s can be sent in cfg80211_scan_request structure
13741 * CR 597966
13742 */
13743 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13744 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13745 pScanInfo->scanAddIE.length = request->ie_len;
13746
13747 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13748 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13749 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013750 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013751 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013752 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013753 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13754 memcpy( pwextBuf->roamProfile.addIEScan,
13755 request->ie, request->ie_len);
13756 }
13757 else
13758 {
13759 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13760 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013761 }
13762
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013763 }
13764 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13765 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13766
13767 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13768 request->ie_len);
13769 if (pP2pIe != NULL)
13770 {
13771#ifdef WLAN_FEATURE_P2P_DEBUG
13772 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13773 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13774 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013775 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013776 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13777 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13778 "Go nego completed to Connection is started");
13779 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13780 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013781 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013782 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13783 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013784 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013785 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13786 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13787 "Disconnected state to Connection is started");
13788 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13789 "for 4way Handshake");
13790 }
13791#endif
13792
13793 /* no_cck will be set during p2p find to disable 11b rates */
13794 if(TRUE == request->no_cck)
13795 {
13796 hddLog(VOS_TRACE_LEVEL_INFO,
13797 "%s: This is a P2P Search", __func__);
13798 scanRequest.p2pSearch = 1;
13799
13800 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013801 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013802 /* set requestType to P2P Discovery */
13803 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13804 }
13805
13806 /*
13807 Skip Dfs Channel in case of P2P Search
13808 if it is set in ini file
13809 */
13810 if(cfg_param->skipDfsChnlInP2pSearch)
13811 {
13812 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013813 }
13814 else
13815 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013816 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013817 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013818
Agarwal Ashish4f616132013-12-30 23:32:50 +053013819 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013820 }
13821 }
13822
13823 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13824
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013825#ifdef FEATURE_WLAN_TDLS
13826 /* if tdls disagree scan right now, return immediately.
13827 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13828 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13829 */
13830 status = wlan_hdd_tdls_scan_callback (pAdapter,
13831 wiphy,
13832#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13833 dev,
13834#endif
13835 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013836 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013837 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053013838 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013839 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13840 "scan rejected %d", __func__, status);
13841 else
13842 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13843 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013844 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053013845 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013846 }
13847#endif
13848
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013849 /* acquire the wakelock to avoid the apps suspend during the scan. To
13850 * address the following issues.
13851 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13852 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13853 * for long time, this result in apps running at full power for long time.
13854 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13855 * be stuck in full power because of resume BMPS
13856 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013857 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013858
Nirav Shah20ac06f2013-12-12 18:14:06 +053013859 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13860 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013861 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13862 scanRequest.requestType, scanRequest.scanType,
13863 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013864 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13865
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013866 if (pHddCtx->spoofMacAddr.isEnabled &&
13867 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053013868 {
13869 hddLog(VOS_TRACE_LEVEL_INFO,
13870 "%s: MAC Spoofing enabled for current scan", __func__);
13871 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13872 * to fill TxBds for probe request during current scan
13873 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013874 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013875 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013876
13877 if(status != VOS_STATUS_SUCCESS)
13878 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013879 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013880 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013881#ifdef FEATURE_WLAN_TDLS
13882 wlan_hdd_tdls_scan_done_callback(pAdapter);
13883#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013884 goto free_mem;
13885 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013886 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013887 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013888 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013889 pAdapter->sessionId, &scanRequest, &scanId,
13890 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013891
Jeff Johnson295189b2012-06-20 16:38:30 -070013892 if (eHAL_STATUS_SUCCESS != status)
13893 {
13894 hddLog(VOS_TRACE_LEVEL_ERROR,
13895 "%s: sme_ScanRequest returned error %d", __func__, status);
13896 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013897 if(eHAL_STATUS_RESOURCES == status)
13898 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013899 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13900 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013901 status = -EBUSY;
13902 } else {
13903 status = -EIO;
13904 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013905 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013906
13907#ifdef FEATURE_WLAN_TDLS
13908 wlan_hdd_tdls_scan_done_callback(pAdapter);
13909#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013910 goto free_mem;
13911 }
13912
13913 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013914 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013915 pAdapter->request = request;
13916 pScanInfo->scanId = scanId;
13917
13918 complete(&pScanInfo->scan_req_completion_event);
13919
13920free_mem:
13921 if( scanRequest.SSIDs.SSIDList )
13922 {
13923 vos_mem_free(scanRequest.SSIDs.SSIDList);
13924 }
13925
13926 if( channelList )
13927 vos_mem_free( channelList );
13928
13929 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013930 return status;
13931}
13932
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013933int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13934#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13935 struct net_device *dev,
13936#endif
13937 struct cfg80211_scan_request *request)
13938{
13939 int ret;
13940
13941 vos_ssr_protect(__func__);
13942 ret = __wlan_hdd_cfg80211_scan(wiphy,
13943#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13944 dev,
13945#endif
13946 request);
13947 vos_ssr_unprotect(__func__);
13948
13949 return ret;
13950}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013951
13952void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13953{
13954 v_U8_t iniDot11Mode =
13955 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13956 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13957
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013958 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13959 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013960 switch ( iniDot11Mode )
13961 {
13962 case eHDD_DOT11_MODE_AUTO:
13963 case eHDD_DOT11_MODE_11ac:
13964 case eHDD_DOT11_MODE_11ac_ONLY:
13965#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013966 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13967 sme_IsFeatureSupportedByFW(DOT11AC) )
13968 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13969 else
13970 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013971#else
13972 hddDot11Mode = eHDD_DOT11_MODE_11n;
13973#endif
13974 break;
13975 case eHDD_DOT11_MODE_11n:
13976 case eHDD_DOT11_MODE_11n_ONLY:
13977 hddDot11Mode = eHDD_DOT11_MODE_11n;
13978 break;
13979 default:
13980 hddDot11Mode = iniDot11Mode;
13981 break;
13982 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013983#ifdef WLAN_FEATURE_AP_HT40_24G
13984 if (operationChannel > SIR_11B_CHANNEL_END)
13985#endif
13986 {
13987 /* This call decides required channel bonding mode */
13988 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013989 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13990 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013991 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013992}
13993
Jeff Johnson295189b2012-06-20 16:38:30 -070013994/*
13995 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013996 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013997 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013998int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013999 const u8 *ssid, size_t ssid_len, const u8 *bssid,
14000 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070014001{
14002 int status = 0;
14003 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080014004 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014005 v_U32_t roamId;
14006 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070014007 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014008 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014009
14010 ENTER();
14011
14012 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080014013 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14014
14015 status = wlan_hdd_validate_context(pHddCtx);
14016 if (status)
14017 {
Yue Mae36e3552014-03-05 17:06:20 -080014018 return status;
14019 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014020
Jeff Johnson295189b2012-06-20 16:38:30 -070014021 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
14022 {
14023 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
14024 return -EINVAL;
14025 }
14026
14027 pRoamProfile = &pWextState->roamProfile;
14028
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014029 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070014030 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014031 hdd_station_ctx_t *pHddStaCtx;
14032 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014033
Siddharth Bhalda0d1622015-04-24 15:47:49 +053014034 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
14035
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014036 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070014037 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
14038 {
14039 /*QoS not enabled in cfg file*/
14040 pRoamProfile->uapsd_mask = 0;
14041 }
14042 else
14043 {
14044 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014045 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070014046 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
14047 }
14048
14049 pRoamProfile->SSIDs.numOfSSIDs = 1;
14050 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
14051 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014052 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070014053 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
14054 ssid, ssid_len);
14055
14056 if (bssid)
14057 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014058 pValidBssid = bssid;
14059 }
14060 else if (bssid_hint)
14061 {
14062 pValidBssid = bssid_hint;
14063 }
14064 if (pValidBssid)
14065 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014066 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014067 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014068 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014069 /* Save BSSID in seperate variable as well, as RoamProfile
14070 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070014071 case of join failure we should send valid BSSID to supplicant
14072 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014073 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014074 WNI_CFG_BSSID_LEN);
14075 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070014076 else
14077 {
14078 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
14079 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014080
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014081 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
14082 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014083 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
14084 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014085 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014086 /*set gen ie*/
14087 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
14088 /*set auth*/
14089 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
14090 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014091#ifdef FEATURE_WLAN_WAPI
14092 if (pAdapter->wapi_info.nWapiMode)
14093 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014094 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014095 switch (pAdapter->wapi_info.wapiAuthMode)
14096 {
14097 case WAPI_AUTH_MODE_PSK:
14098 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014099 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014100 pAdapter->wapi_info.wapiAuthMode);
14101 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
14102 break;
14103 }
14104 case WAPI_AUTH_MODE_CERT:
14105 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014106 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014107 pAdapter->wapi_info.wapiAuthMode);
14108 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
14109 break;
14110 }
14111 } // End of switch
14112 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
14113 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
14114 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014115 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014116 pRoamProfile->AuthType.numEntries = 1;
14117 pRoamProfile->EncryptionType.numEntries = 1;
14118 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14119 pRoamProfile->mcEncryptionType.numEntries = 1;
14120 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14121 }
14122 }
14123#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014124#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014125 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014126 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14127 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
14128 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014129 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
14130 sizeof (tSirGtkOffloadParams));
14131 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014132 }
14133#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014134 pRoamProfile->csrPersona = pAdapter->device_mode;
14135
Jeff Johnson32d95a32012-09-10 13:15:23 -070014136 if( operatingChannel )
14137 {
14138 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
14139 pRoamProfile->ChannelInfo.numOfChannels = 1;
14140 }
Chet Lanctot186b5732013-03-18 10:26:30 -070014141 else
14142 {
14143 pRoamProfile->ChannelInfo.ChannelList = NULL;
14144 pRoamProfile->ChannelInfo.numOfChannels = 0;
14145 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014146 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
14147 {
14148 hdd_select_cbmode(pAdapter,operatingChannel);
14149 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014150
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014151 /*
14152 * Change conn_state to connecting before sme_RoamConnect(),
14153 * because sme_RoamConnect() has a direct path to call
14154 * hdd_smeRoamCallback(), which will change the conn_state
14155 * If direct path, conn_state will be accordingly changed
14156 * to NotConnected or Associated by either
14157 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
14158 * in sme_RoamCallback()
14159 * if sme_RomConnect is to be queued,
14160 * Connecting state will remain until it is completed.
14161 * If connection state is not changed,
14162 * connection state will remain in eConnectionState_NotConnected state.
14163 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
14164 * if conn state is eConnectionState_NotConnected.
14165 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
14166 * informed of connect result indication which is an issue.
14167 */
14168
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014169 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14170 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053014171 {
14172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014173 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014174 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
14175 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053014176 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014177 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014178 pAdapter->sessionId, pRoamProfile, &roamId);
14179
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014180 if ((eHAL_STATUS_SUCCESS != status) &&
14181 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14182 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014183
14184 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014185 hddLog(VOS_TRACE_LEVEL_ERROR,
14186 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
14187 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014188 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014189 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014190 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014191 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014192
14193 pRoamProfile->ChannelInfo.ChannelList = NULL;
14194 pRoamProfile->ChannelInfo.numOfChannels = 0;
14195
Jeff Johnson295189b2012-06-20 16:38:30 -070014196 }
14197 else
14198 {
14199 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
14200 return -EINVAL;
14201 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080014202 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014203 return status;
14204}
14205
14206/*
14207 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
14208 * This function is used to set the authentication type (OPEN/SHARED).
14209 *
14210 */
14211static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
14212 enum nl80211_auth_type auth_type)
14213{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014214 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014215 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14216
14217 ENTER();
14218
14219 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014220 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070014221 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014222 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014223 hddLog(VOS_TRACE_LEVEL_INFO,
14224 "%s: set authentication type to AUTOSWITCH", __func__);
14225 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
14226 break;
14227
14228 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014229#ifdef WLAN_FEATURE_VOWIFI_11R
14230 case NL80211_AUTHTYPE_FT:
14231#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014232 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014233 "%s: set authentication type to OPEN", __func__);
14234 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
14235 break;
14236
14237 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014238 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014239 "%s: set authentication type to SHARED", __func__);
14240 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
14241 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014242#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014243 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014244 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014245 "%s: set authentication type to CCKM WPA", __func__);
14246 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
14247 break;
14248#endif
14249
14250
14251 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014252 hddLog(VOS_TRACE_LEVEL_ERROR,
14253 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014254 auth_type);
14255 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
14256 return -EINVAL;
14257 }
14258
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014259 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014260 pHddStaCtx->conn_info.authType;
14261 return 0;
14262}
14263
14264/*
14265 * FUNCTION: wlan_hdd_set_akm_suite
14266 * This function is used to set the key mgmt type(PSK/8021x).
14267 *
14268 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014269static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014270 u32 key_mgmt
14271 )
14272{
14273 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14274 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053014275 /* Should be in ieee802_11_defs.h */
14276#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
14277#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070014278 /*set key mgmt type*/
14279 switch(key_mgmt)
14280 {
14281 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053014282 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014283#ifdef WLAN_FEATURE_VOWIFI_11R
14284 case WLAN_AKM_SUITE_FT_PSK:
14285#endif
14286 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070014287 __func__);
14288 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
14289 break;
14290
14291 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053014292 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014293#ifdef WLAN_FEATURE_VOWIFI_11R
14294 case WLAN_AKM_SUITE_FT_8021X:
14295#endif
14296 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070014297 __func__);
14298 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14299 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014300#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014301#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
14302#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
14303 case WLAN_AKM_SUITE_CCKM:
14304 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
14305 __func__);
14306 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
14307 break;
14308#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070014309#ifndef WLAN_AKM_SUITE_OSEN
14310#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
14311 case WLAN_AKM_SUITE_OSEN:
14312 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
14313 __func__);
14314 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14315 break;
14316#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014317
14318 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014319 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014320 __func__, key_mgmt);
14321 return -EINVAL;
14322
14323 }
14324 return 0;
14325}
14326
14327/*
14328 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014329 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070014330 * (NONE/WEP40/WEP104/TKIP/CCMP).
14331 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014332static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
14333 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070014334 bool ucast
14335 )
14336{
14337 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014338 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014339 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14340
14341 ENTER();
14342
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014343 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014344 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014345 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070014346 __func__, cipher);
14347 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14348 }
14349 else
14350 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014351
Jeff Johnson295189b2012-06-20 16:38:30 -070014352 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014353 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014354 {
14355 case IW_AUTH_CIPHER_NONE:
14356 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14357 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014358
Jeff Johnson295189b2012-06-20 16:38:30 -070014359 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014360 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070014361 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014362
Jeff Johnson295189b2012-06-20 16:38:30 -070014363 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014364 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070014365 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014366
Jeff Johnson295189b2012-06-20 16:38:30 -070014367 case WLAN_CIPHER_SUITE_TKIP:
14368 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
14369 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014370
Jeff Johnson295189b2012-06-20 16:38:30 -070014371 case WLAN_CIPHER_SUITE_CCMP:
14372 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14373 break;
14374#ifdef FEATURE_WLAN_WAPI
14375 case WLAN_CIPHER_SUITE_SMS4:
14376 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
14377 break;
14378#endif
14379
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014380#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014381 case WLAN_CIPHER_SUITE_KRK:
14382 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
14383 break;
14384#endif
14385 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014386 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014387 __func__, cipher);
14388 return -EOPNOTSUPP;
14389 }
14390 }
14391
14392 if (ucast)
14393 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014394 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014395 __func__, encryptionType);
14396 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14397 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014398 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014399 encryptionType;
14400 }
14401 else
14402 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014403 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014404 __func__, encryptionType);
14405 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
14406 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
14407 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
14408 }
14409
14410 return 0;
14411}
14412
14413
14414/*
14415 * FUNCTION: wlan_hdd_cfg80211_set_ie
14416 * This function is used to parse WPA/RSN IE's.
14417 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014418int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014419#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14420 const u8 *ie,
14421#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014422 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014423#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014424 size_t ie_len
14425 )
14426{
14427 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014428#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14429 const u8 *genie = ie;
14430#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014431 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014432#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014433 v_U16_t remLen = ie_len;
14434#ifdef FEATURE_WLAN_WAPI
14435 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
14436 u16 *tmp;
14437 v_U16_t akmsuiteCount;
14438 int *akmlist;
14439#endif
14440 ENTER();
14441
14442 /* clear previous assocAddIE */
14443 pWextState->assocAddIE.length = 0;
14444 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014445 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014446
14447 while (remLen >= 2)
14448 {
14449 v_U16_t eLen = 0;
14450 v_U8_t elementId;
14451 elementId = *genie++;
14452 eLen = *genie++;
14453 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014454
Arif Hussain6d2a3322013-11-17 19:50:10 -080014455 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070014456 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014457
14458 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070014459 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014460 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014461 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 -070014462 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014463 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014464 "%s: Invalid WPA IE", __func__);
14465 return -EINVAL;
14466 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014467 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070014468 {
14469 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014470 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014471 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014472
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014473 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014474 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014475 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
14476 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014477 VOS_ASSERT(0);
14478 return -ENOMEM;
14479 }
14480 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14481 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14482 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014483
Jeff Johnson295189b2012-06-20 16:38:30 -070014484 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
14485 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14486 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14487 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014488 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
14489 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014490 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
14491 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14492 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
14493 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
14494 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
14495 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014496 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053014497 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070014498 {
14499 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014500 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014501 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014502
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014503 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014504 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014505 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14506 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014507 VOS_ASSERT(0);
14508 return -ENOMEM;
14509 }
14510 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14511 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14512 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014513
Jeff Johnson295189b2012-06-20 16:38:30 -070014514 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14515 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14516 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014517#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014518 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
14519 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014520 /*Consider WFD IE, only for P2P Client */
14521 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
14522 {
14523 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014524 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014525 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014526
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014527 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014528 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014529 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14530 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014531 VOS_ASSERT(0);
14532 return -ENOMEM;
14533 }
14534 // WFD IE is saved to Additional IE ; it should be accumulated to handle
14535 // WPS IE + P2P IE + WFD IE
14536 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14537 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014538
Jeff Johnson295189b2012-06-20 16:38:30 -070014539 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14540 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14541 }
14542#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014543 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014544 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014545 HS20_OUI_TYPE_SIZE)) )
14546 {
14547 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014548 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014549 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014550
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014551 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014552 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014553 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14554 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014555 VOS_ASSERT(0);
14556 return -ENOMEM;
14557 }
14558 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14559 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014560
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014561 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14562 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14563 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014564 /* Appending OSEN Information Element in Assiciation Request */
14565 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
14566 OSEN_OUI_TYPE_SIZE)) )
14567 {
14568 v_U16_t curAddIELen = pWextState->assocAddIE.length;
14569 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
14570 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014571
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014572 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014573 {
14574 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14575 "Need bigger buffer space");
14576 VOS_ASSERT(0);
14577 return -ENOMEM;
14578 }
14579 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14580 pWextState->assocAddIE.length += eLen + 2;
14581
14582 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
14583 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14584 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14585 }
14586
Abhishek Singh4322e622015-06-10 15:42:54 +053014587 /* Update only for WPA IE */
14588 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
14589 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014590
14591 /* populating as ADDIE in beacon frames */
14592 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014593 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014594 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
14595 {
14596 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14597 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
14598 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14599 {
14600 hddLog(LOGE,
14601 "Coldn't pass "
14602 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
14603 }
14604 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
14605 else
14606 hddLog(LOGE,
14607 "Could not pass on "
14608 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
14609
14610 /* IBSS mode doesn't contain params->proberesp_ies still
14611 beaconIE's need to be populated in probe response frames */
14612 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
14613 {
14614 u16 rem_probe_resp_ie_len = eLen + 2;
14615 u8 probe_rsp_ie_len[3] = {0};
14616 u8 counter = 0;
14617
14618 /* Check Probe Resp Length if it is greater then 255 then
14619 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
14620 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
14621 not able Store More then 255 bytes into One Variable */
14622
14623 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
14624 {
14625 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
14626 {
14627 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
14628 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
14629 }
14630 else
14631 {
14632 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
14633 rem_probe_resp_ie_len = 0;
14634 }
14635 }
14636
14637 rem_probe_resp_ie_len = 0;
14638
14639 if (probe_rsp_ie_len[0] > 0)
14640 {
14641 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14642 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
14643 (tANI_U8*)(genie - 2),
14644 probe_rsp_ie_len[0], NULL,
14645 eANI_BOOLEAN_FALSE)
14646 == eHAL_STATUS_FAILURE)
14647 {
14648 hddLog(LOGE,
14649 "Could not pass"
14650 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
14651 }
14652 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
14653 }
14654
14655 if (probe_rsp_ie_len[1] > 0)
14656 {
14657 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14658 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
14659 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14660 probe_rsp_ie_len[1], NULL,
14661 eANI_BOOLEAN_FALSE)
14662 == eHAL_STATUS_FAILURE)
14663 {
14664 hddLog(LOGE,
14665 "Could not pass"
14666 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
14667 }
14668 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
14669 }
14670
14671 if (probe_rsp_ie_len[2] > 0)
14672 {
14673 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14674 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
14675 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14676 probe_rsp_ie_len[2], NULL,
14677 eANI_BOOLEAN_FALSE)
14678 == eHAL_STATUS_FAILURE)
14679 {
14680 hddLog(LOGE,
14681 "Could not pass"
14682 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
14683 }
14684 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
14685 }
14686
14687 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14688 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
14689 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14690 {
14691 hddLog(LOGE,
14692 "Could not pass"
14693 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
14694 }
14695 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014696 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014697 break;
14698 case DOT11F_EID_RSN:
14699 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
14700 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14701 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
14702 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
14703 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
14704 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053014705
Abhishek Singhb16f3562016-01-20 11:08:32 +053014706 /* Appending extended capabilities with Interworking or
14707 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053014708 *
14709 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053014710 * interworkingService or bsstransition bit is set to 1.
14711 * Driver is only interested in interworkingService and
14712 * bsstransition capability from supplicant.
14713 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053014714 * required from supplicat, it needs to be handled while
14715 * sending Assoc Req in LIM.
14716 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014717 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014718 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014719 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014720 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014721 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014722
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014723 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014724 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014725 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14726 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014727 VOS_ASSERT(0);
14728 return -ENOMEM;
14729 }
14730 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14731 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014732
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014733 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14734 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14735 break;
14736 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014737#ifdef FEATURE_WLAN_WAPI
14738 case WLAN_EID_WAPI:
14739 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014740 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014741 pAdapter->wapi_info.nWapiMode);
14742 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014743 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014744 akmsuiteCount = WPA_GET_LE16(tmp);
14745 tmp = tmp + 1;
14746 akmlist = (int *)(tmp);
14747 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14748 {
14749 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14750 }
14751 else
14752 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014753 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014754 VOS_ASSERT(0);
14755 return -EINVAL;
14756 }
14757
14758 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14759 {
14760 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014761 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014762 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014763 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014764 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014765 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014766 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014767 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014768 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14769 }
14770 break;
14771#endif
14772 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014773 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014774 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014775 /* when Unknown IE is received we should break and continue
14776 * to the next IE in the buffer instead we were returning
14777 * so changing this to break */
14778 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014779 }
14780 genie += eLen;
14781 remLen -= eLen;
14782 }
14783 EXIT();
14784 return 0;
14785}
14786
14787/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014788 * FUNCTION: hdd_isWPAIEPresent
14789 * Parse the received IE to find the WPA IE
14790 *
14791 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014792static bool hdd_isWPAIEPresent(
14793#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14794 const u8 *ie,
14795#else
14796 u8 *ie,
14797#endif
14798 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014799{
14800 v_U8_t eLen = 0;
14801 v_U16_t remLen = ie_len;
14802 v_U8_t elementId = 0;
14803
14804 while (remLen >= 2)
14805 {
14806 elementId = *ie++;
14807 eLen = *ie++;
14808 remLen -= 2;
14809 if (eLen > remLen)
14810 {
14811 hddLog(VOS_TRACE_LEVEL_ERROR,
14812 "%s: IE length is wrong %d", __func__, eLen);
14813 return FALSE;
14814 }
14815 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14816 {
14817 /* OUI - 0x00 0X50 0XF2
14818 WPA Information Element - 0x01
14819 WPA version - 0x01*/
14820 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14821 return TRUE;
14822 }
14823 ie += eLen;
14824 remLen -= eLen;
14825 }
14826 return FALSE;
14827}
14828
14829/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014830 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014831 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014832 * parameters during connect operation.
14833 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014834int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014835 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014836 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014837{
14838 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014839 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014840 ENTER();
14841
14842 /*set wpa version*/
14843 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14844
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014845 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014846 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014847 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014848 {
14849 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14850 }
14851 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14852 {
14853 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14854 }
14855 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014856
14857 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014858 pWextState->wpaVersion);
14859
14860 /*set authentication type*/
14861 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14862
14863 if (0 > status)
14864 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014865 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014866 "%s: failed to set authentication type ", __func__);
14867 return status;
14868 }
14869
14870 /*set key mgmt type*/
14871 if (req->crypto.n_akm_suites)
14872 {
14873 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14874 if (0 > status)
14875 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014876 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014877 __func__);
14878 return status;
14879 }
14880 }
14881
14882 /*set pairwise cipher type*/
14883 if (req->crypto.n_ciphers_pairwise)
14884 {
14885 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14886 req->crypto.ciphers_pairwise[0], true);
14887 if (0 > status)
14888 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014889 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014890 "%s: failed to set unicast cipher type", __func__);
14891 return status;
14892 }
14893 }
14894 else
14895 {
14896 /*Reset previous cipher suite to none*/
14897 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14898 if (0 > status)
14899 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014900 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014901 "%s: failed to set unicast cipher type", __func__);
14902 return status;
14903 }
14904 }
14905
14906 /*set group cipher type*/
14907 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14908 false);
14909
14910 if (0 > status)
14911 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014912 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014913 __func__);
14914 return status;
14915 }
14916
Chet Lanctot186b5732013-03-18 10:26:30 -070014917#ifdef WLAN_FEATURE_11W
14918 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14919#endif
14920
Jeff Johnson295189b2012-06-20 16:38:30 -070014921 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14922 if (req->ie_len)
14923 {
14924 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14925 if ( 0 > status)
14926 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014927 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014928 __func__);
14929 return status;
14930 }
14931 }
14932
14933 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014934 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014935 {
14936 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14937 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14938 )
14939 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014940 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014941 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14942 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014943 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014944 __func__);
14945 return -EOPNOTSUPP;
14946 }
14947 else
14948 {
14949 u8 key_len = req->key_len;
14950 u8 key_idx = req->key_idx;
14951
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014952 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014953 && (CSR_MAX_NUM_KEY > key_idx)
14954 )
14955 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014956 hddLog(VOS_TRACE_LEVEL_INFO,
14957 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014958 __func__, key_idx, key_len);
14959 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014960 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014961 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014962 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014963 (u8)key_len;
14964 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14965 }
14966 }
14967 }
14968 }
14969
14970 return status;
14971}
14972
14973/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014974 * FUNCTION: wlan_hdd_try_disconnect
14975 * This function is used to disconnect from previous
14976 * connection
14977 */
14978static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
14979{
14980 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014981 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014982 hdd_station_ctx_t *pHddStaCtx;
14983 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014984 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014985
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014986 ret = wlan_hdd_validate_context(pHddCtx);
14987 if (0 != ret)
14988 {
14989 return ret;
14990 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014991 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14992
14993 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14994
14995 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14996 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053014997 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014998 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14999 {
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015000 spin_lock_bh(&pAdapter->lock_for_active_session);
15001 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15002 {
15003 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15004 }
15005 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053015006 hdd_connSetConnectionState(pHddStaCtx,
15007 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015008 /* Issue disconnect to CSR */
15009 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015010 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015011 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015012 eCSR_DISCONNECT_REASON_UNSPECIFIED);
15013 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
15014 hddLog(LOG1,
15015 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
15016 } else if ( 0 != status ) {
15017 hddLog(LOGE,
15018 FL("csrRoamDisconnect failure, returned %d"),
15019 (int)status );
15020 result = -EINVAL;
15021 goto disconnected;
15022 }
15023 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015024 &pAdapter->disconnect_comp_var,
15025 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015026 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
15027 hddLog(LOGE,
15028 "%s: Failed to disconnect, timed out", __func__);
15029 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015030 }
15031 }
15032 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
15033 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015034 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015035 &pAdapter->disconnect_comp_var,
15036 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015037 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015038 {
15039 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015040 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015041 }
15042 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015043disconnected:
15044 hddLog(LOG1,
15045 FL("Set HDD connState to eConnectionState_NotConnected"));
15046 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
15047 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015048}
15049
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015050/**
15051 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
15052 * @adapter: Pointer to the HDD adapter
15053 * @req: Pointer to the structure cfg_connect_params receieved from user space
15054 *
15055 * This function will start reassociation if bssid hint, channel hint and
15056 * previous bssid parameters are present in the connect request
15057 *
15058 * Return: success if reassociation is happening
15059 * Error code if reassociation is not permitted or not happening
15060 */
15061#ifdef CFG80211_CONNECT_PREV_BSSID
15062static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15063 struct cfg80211_connect_params *req)
15064{
15065 int status = -EPERM;
15066 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
15067 hddLog(VOS_TRACE_LEVEL_INFO,
15068 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
15069 req->channel_hint->hw_value,
15070 MAC_ADDR_ARRAY(req->bssid_hint));
15071 status = hdd_reassoc(adapter, req->bssid_hint,
15072 req->channel_hint->hw_value,
15073 CONNECT_CMD_USERSPACE);
15074 }
15075 return status;
15076}
15077#else
15078static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15079 struct cfg80211_connect_params *req)
15080{
15081 return -EPERM;
15082}
15083#endif
15084
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015085/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053015086 * FUNCTION: __wlan_hdd_cfg80211_connect
15087 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015088 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015089static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015090 struct net_device *ndev,
15091 struct cfg80211_connect_params *req
15092 )
15093{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015094 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015095 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053015096#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
15097 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015098 const u8 *bssid_hint = req->bssid_hint;
15099#else
15100 const u8 *bssid_hint = NULL;
15101#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015102 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015103 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053015104 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015105
15106 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015107
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015108 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15109 TRACE_CODE_HDD_CFG80211_CONNECT,
15110 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015111 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015112 "%s: device_mode = %s (%d)", __func__,
15113 hdd_device_modetoString(pAdapter->device_mode),
15114 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015115
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015116 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015117 if (!pHddCtx)
15118 {
15119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15120 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015121 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015122 }
15123
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015124 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015125 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015126 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015127 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015128 }
15129
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015130 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
15131 if (0 == status)
15132 return status;
15133
Agarwal Ashish51325b52014-06-16 16:50:49 +053015134
Jeff Johnson295189b2012-06-20 16:38:30 -070015135#ifdef WLAN_BTAMP_FEATURE
15136 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015137 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070015138 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015139 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015140 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080015141 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070015142 }
15143#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015144
15145 //If Device Mode is Station Concurrent Sessions Exit BMps
15146 //P2P Mode will be taken care in Open/close adapter
15147 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053015148 (vos_concurrent_open_sessions_running())) {
15149 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
15150 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015151 }
15152
15153 /*Try disconnecting if already in connected state*/
15154 status = wlan_hdd_try_disconnect(pAdapter);
15155 if ( 0 > status)
15156 {
15157 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15158 " connection"));
15159 return -EALREADY;
15160 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053015161 /* Check for max concurrent connections after doing disconnect if any*/
15162 if (vos_max_concurrent_connections_reached()) {
15163 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15164 return -ECONNREFUSED;
15165 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015166
Jeff Johnson295189b2012-06-20 16:38:30 -070015167 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015168 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070015169
15170 if ( 0 > status)
15171 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015172 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070015173 __func__);
15174 return status;
15175 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053015176
15177 if (pHddCtx->spoofMacAddr.isEnabled)
15178 {
15179 hddLog(VOS_TRACE_LEVEL_INFO,
15180 "%s: MAC Spoofing enabled ", __func__);
15181 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15182 * to fill TxBds for probe request during SSID scan which may happen
15183 * as part of connect command
15184 */
15185 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
15186 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
15187 if (status != VOS_STATUS_SUCCESS)
15188 return -ECONNREFUSED;
15189 }
15190
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015191 if (req->channel)
15192 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070015193 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015194 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053015195
15196 /* Abort if any scan is going on */
15197 status = wlan_hdd_scan_abort(pAdapter);
15198 if (0 != status)
15199 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
15200
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015201 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
15202 req->ssid_len, req->bssid,
15203 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015204
Sushant Kaushikd7083982015-03-18 14:33:24 +053015205 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015206 {
15207 //ReEnable BMPS if disabled
15208 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
15209 (NULL != pHddCtx))
15210 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053015211 if (pHddCtx->hdd_wlan_suspended)
15212 {
15213 hdd_set_pwrparams(pHddCtx);
15214 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015215 //ReEnable Bmps and Imps back
15216 hdd_enable_bmps_imps(pHddCtx);
15217 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015218 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070015219 return status;
15220 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015221 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015222 EXIT();
15223 return status;
15224}
15225
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015226static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
15227 struct net_device *ndev,
15228 struct cfg80211_connect_params *req)
15229{
15230 int ret;
15231 vos_ssr_protect(__func__);
15232 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
15233 vos_ssr_unprotect(__func__);
15234
15235 return ret;
15236}
Jeff Johnson295189b2012-06-20 16:38:30 -070015237
15238/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015239 * FUNCTION: wlan_hdd_disconnect
15240 * This function is used to issue a disconnect request to SME
15241 */
15242int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
15243{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015244 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015245 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015246 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015247 long ret;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015248 eConnectionState prev_conn_state;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015249
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015250 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015251
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015252 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015253 if (0 != status)
15254 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015255 return status;
15256 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053015257 /* Indicate sme of disconnect so that in progress connection or preauth
15258 * can be aborted
15259 */
15260 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053015261 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015262 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015263
Agarwal Ashish47d18112014-08-04 19:55:07 +053015264 /* Need to apply spin lock before decreasing active sessions
15265 * as there can be chance for double decrement if context switch
15266 * Calls hdd_DisConnectHandler.
15267 */
15268
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015269 prev_conn_state = pHddStaCtx->conn_info.connState;
15270
Agarwal Ashish47d18112014-08-04 19:55:07 +053015271 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015272 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15273 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015274 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15275 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053015276 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
15277 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015278
Abhishek Singhf4669da2014-05-26 15:07:49 +053015279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053015280 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
15281
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015282 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015283
Mihir Shete182a0b22014-08-18 16:08:48 +053015284 /*
15285 * stop tx queues before deleting STA/BSS context from the firmware.
15286 * tx has to be disabled because the firmware can get busy dropping
15287 * the tx frames after BSS/STA has been deleted and will not send
15288 * back a response resulting in WDI timeout
15289 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053015290 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053015291 netif_tx_disable(pAdapter->dev);
15292 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015293
Mihir Shete182a0b22014-08-18 16:08:48 +053015294 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015295 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
15296 pAdapter->sessionId, reason);
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015297 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
15298 prev_conn_state != eConnectionState_Connecting)
15299 {
15300 hddLog(LOG1,
15301 FL("status = %d, already disconnected"), status);
15302 result = 0;
15303 goto disconnected;
15304 }
15305 /*
15306 * Wait here instead of returning directly, this will block the next
15307 * connect command and allow processing of the scan for ssid and
15308 * the previous connect command in CSR. Else we might hit some
15309 * race conditions leading to SME and HDD out of sync.
15310 */
15311 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015312 {
15313 hddLog(LOG1,
15314 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015315 }
15316 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015317 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015318 hddLog(LOGE,
15319 FL("csrRoamDisconnect failure, returned %d"),
15320 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015321 result = -EINVAL;
15322 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015323 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015324 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015325 &pAdapter->disconnect_comp_var,
15326 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015327 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015328 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015329 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015330 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015331 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015332 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015333disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015334 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015335 FL("Set HDD connState to eConnectionState_NotConnected"));
15336 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015337#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
15338 /* Sending disconnect event to userspace for kernel version < 3.11
15339 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
15340 */
15341 hddLog(LOG1, FL("Send disconnected event to userspace"));
15342
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053015343 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015344 WLAN_REASON_UNSPECIFIED);
15345#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015346
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015347 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015348 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015349}
15350
15351
15352/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015353 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070015354 * This function is used to issue a disconnect request to SME
15355 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015356static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015357 struct net_device *dev,
15358 u16 reason
15359 )
15360{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015361 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015362 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015363 tCsrRoamProfile *pRoamProfile;
15364 hdd_station_ctx_t *pHddStaCtx;
15365 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015366#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015367 tANI_U8 staIdx;
15368#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015369
Jeff Johnson295189b2012-06-20 16:38:30 -070015370 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015371
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015372 if (!pAdapter) {
15373 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15374 return -EINVAL;
15375 }
15376
15377 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15378 if (!pHddStaCtx) {
15379 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
15380 return -EINVAL;
15381 }
15382
15383 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15384 status = wlan_hdd_validate_context(pHddCtx);
15385 if (0 != status)
15386 {
15387 return status;
15388 }
15389
15390 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
15391
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015392 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15393 TRACE_CODE_HDD_CFG80211_DISCONNECT,
15394 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015395 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
15396 __func__, hdd_device_modetoString(pAdapter->device_mode),
15397 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015398
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015399 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
15400 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070015401
Jeff Johnson295189b2012-06-20 16:38:30 -070015402 if (NULL != pRoamProfile)
15403 {
15404 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015405 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
15406 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070015407 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015408 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070015409 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015410 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070015411 switch(reason)
15412 {
15413 case WLAN_REASON_MIC_FAILURE:
15414 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
15415 break;
15416
15417 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
15418 case WLAN_REASON_DISASSOC_AP_BUSY:
15419 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
15420 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
15421 break;
15422
15423 case WLAN_REASON_PREV_AUTH_NOT_VALID:
15424 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053015425 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070015426 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
15427 break;
15428
Jeff Johnson295189b2012-06-20 16:38:30 -070015429 default:
15430 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
15431 break;
15432 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015433 pScanInfo = &pHddCtx->scan_info;
15434 if (pScanInfo->mScanPending)
15435 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015436 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015437 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015438 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015439 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015440 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053015441 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015442#ifdef FEATURE_WLAN_TDLS
15443 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015444 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015445 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015446 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
15447 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015448 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015449 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015450 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015451 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015452 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015453 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015454 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015455 status = sme_DeleteTdlsPeerSta(
15456 WLAN_HDD_GET_HAL_CTX(pAdapter),
15457 pAdapter->sessionId,
15458 mac);
15459 if (status != eHAL_STATUS_SUCCESS) {
15460 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15461 return -EPERM;
15462 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015463 }
15464 }
15465#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015466
15467 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
15468 reasonCode,
15469 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015470 status = wlan_hdd_disconnect(pAdapter, reasonCode);
15471 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070015472 {
15473 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015474 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015475 __func__, (int)status );
15476 return -EINVAL;
15477 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015478 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015479 else
15480 {
15481 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
15482 "called while in %d state", __func__,
15483 pHddStaCtx->conn_info.connState);
15484 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015485 }
15486 else
15487 {
15488 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
15489 }
15490
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015491 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015492 return status;
15493}
15494
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015495static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
15496 struct net_device *dev,
15497 u16 reason
15498 )
15499{
15500 int ret;
15501 vos_ssr_protect(__func__);
15502 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
15503 vos_ssr_unprotect(__func__);
15504
15505 return ret;
15506}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015507
Jeff Johnson295189b2012-06-20 16:38:30 -070015508/*
15509 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015510 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015511 * settings in IBSS mode.
15512 */
15513static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015514 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015515 struct cfg80211_ibss_params *params
15516 )
15517{
15518 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015519 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015520 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15521 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015522
Jeff Johnson295189b2012-06-20 16:38:30 -070015523 ENTER();
15524
15525 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070015526 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070015527
15528 if (params->ie_len && ( NULL != params->ie) )
15529 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015530 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15531 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015532 {
15533 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15534 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15535 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015536 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015537 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015538 tDot11fIEWPA dot11WPAIE;
15539 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015540 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015541
Wilson Yang00256342013-10-10 23:13:38 -070015542 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015543 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15544 params->ie_len, DOT11F_EID_WPA);
15545 if ( NULL != ie )
15546 {
15547 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15548 // Unpack the WPA IE
15549 //Skip past the EID byte and length byte - and four byte WiFi OUI
15550 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
15551 &ie[2+4],
15552 ie[1] - 4,
15553 &dot11WPAIE);
15554 /*Extract the multicast cipher, the encType for unicast
15555 cipher for wpa-none is none*/
15556 encryptionType =
15557 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
15558 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015559 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015560
Jeff Johnson295189b2012-06-20 16:38:30 -070015561 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
15562
15563 if (0 > status)
15564 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015565 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015566 __func__);
15567 return status;
15568 }
15569 }
15570
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015571 pWextState->roamProfile.AuthType.authType[0] =
15572 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070015573 eCSR_AUTH_TYPE_OPEN_SYSTEM;
15574
15575 if (params->privacy)
15576 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015577 /* Security enabled IBSS, At this time there is no information available
15578 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070015579 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015580 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070015581 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015582 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070015583 *enable privacy bit in beacons */
15584
15585 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
15586 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015587 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
15588 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070015589 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15590 pWextState->roamProfile.EncryptionType.numEntries = 1;
15591 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070015592 return status;
15593}
15594
15595/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015596 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015597 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015598 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015599static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015600 struct net_device *dev,
15601 struct cfg80211_ibss_params *params
15602 )
15603{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015604 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015605 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15606 tCsrRoamProfile *pRoamProfile;
15607 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015608 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15609 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015610 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070015611
15612 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015613
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015614 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15615 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
15616 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015617 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015618 "%s: device_mode = %s (%d)", __func__,
15619 hdd_device_modetoString(pAdapter->device_mode),
15620 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015621
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015622 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015623 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015624 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015625 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015626 }
15627
15628 if (NULL == pWextState)
15629 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015630 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015631 __func__);
15632 return -EIO;
15633 }
15634
Agarwal Ashish51325b52014-06-16 16:50:49 +053015635 if (vos_max_concurrent_connections_reached()) {
15636 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15637 return -ECONNREFUSED;
15638 }
15639
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015640 /*Try disconnecting if already in connected state*/
15641 status = wlan_hdd_try_disconnect(pAdapter);
15642 if ( 0 > status)
15643 {
15644 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15645 " IBSS connection"));
15646 return -EALREADY;
15647 }
15648
Jeff Johnson295189b2012-06-20 16:38:30 -070015649 pRoamProfile = &pWextState->roamProfile;
15650
15651 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
15652 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015653 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015654 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015655 return -EINVAL;
15656 }
15657
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015658 /* BSSID is provided by upper layers hence no need to AUTO generate */
15659 if (NULL != params->bssid) {
15660 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15661 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
15662 hddLog (VOS_TRACE_LEVEL_ERROR,
15663 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15664 return -EIO;
15665 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015666 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015667 }
krunal sonie9002db2013-11-25 14:24:17 -080015668 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
15669 {
15670 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15671 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
15672 {
15673 hddLog (VOS_TRACE_LEVEL_ERROR,
15674 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15675 return -EIO;
15676 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015677
15678 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080015679 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015680 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080015681 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015682
Jeff Johnson295189b2012-06-20 16:38:30 -070015683 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070015684 if (NULL !=
15685#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15686 params->chandef.chan)
15687#else
15688 params->channel)
15689#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015690 {
15691 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015692 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15693 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
15694 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15695 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015696
15697 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015698 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070015699 ieee80211_frequency_to_channel(
15700#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15701 params->chandef.chan->center_freq);
15702#else
15703 params->channel->center_freq);
15704#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015705
15706 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15707 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070015708 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015709 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
15710 __func__);
15711 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070015712 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015713
15714 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015715 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015716 if (channelNum == validChan[indx])
15717 {
15718 break;
15719 }
15720 }
15721 if (indx >= numChans)
15722 {
15723 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015724 __func__, channelNum);
15725 return -EINVAL;
15726 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015727 /* Set the Operational Channel */
15728 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
15729 channelNum);
15730 pRoamProfile->ChannelInfo.numOfChannels = 1;
15731 pHddStaCtx->conn_info.operationChannel = channelNum;
15732 pRoamProfile->ChannelInfo.ChannelList =
15733 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070015734 }
15735
15736 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015737 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070015738 if (status < 0)
15739 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015740 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070015741 __func__);
15742 return status;
15743 }
15744
15745 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015746 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053015747 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015748 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015749
15750 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015751 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015752
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015753 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015754 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015755}
15756
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015757static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
15758 struct net_device *dev,
15759 struct cfg80211_ibss_params *params
15760 )
15761{
15762 int ret = 0;
15763
15764 vos_ssr_protect(__func__);
15765 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
15766 vos_ssr_unprotect(__func__);
15767
15768 return ret;
15769}
15770
Jeff Johnson295189b2012-06-20 16:38:30 -070015771/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015772 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015773 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015774 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015775static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015776 struct net_device *dev
15777 )
15778{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015779 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015780 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15781 tCsrRoamProfile *pRoamProfile;
15782 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015783 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053015784 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015785#ifdef WLAN_FEATURE_RMC
15786 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
15787#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015788
15789 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015790
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015791 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15792 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
15793 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015794 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015795 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015796 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015797 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015798 }
15799
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015800 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
15801 hdd_device_modetoString(pAdapter->device_mode),
15802 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015803 if (NULL == pWextState)
15804 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015805 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015806 __func__);
15807 return -EIO;
15808 }
15809
15810 pRoamProfile = &pWextState->roamProfile;
15811
15812 /* Issue disconnect only if interface type is set to IBSS */
15813 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
15814 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015815 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070015816 __func__);
15817 return -EINVAL;
15818 }
15819
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015820#ifdef WLAN_FEATURE_RMC
15821 /* Clearing add IE of beacon */
15822 if (ccmCfgSetStr(pHddCtx->hHal,
15823 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
15824 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
15825 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15826 {
15827 hddLog (VOS_TRACE_LEVEL_ERROR,
15828 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
15829 return -EINVAL;
15830 }
15831 if (ccmCfgSetInt(pHddCtx->hHal,
15832 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
15833 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15834 {
15835 hddLog (VOS_TRACE_LEVEL_ERROR,
15836 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
15837 __func__);
15838 return -EINVAL;
15839 }
15840
15841 // Reset WNI_CFG_PROBE_RSP Flags
15842 wlan_hdd_reset_prob_rspies(pAdapter);
15843
15844 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15845 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
15846 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15847 {
15848 hddLog (VOS_TRACE_LEVEL_ERROR,
15849 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
15850 __func__);
15851 return -EINVAL;
15852 }
15853#endif
15854
Jeff Johnson295189b2012-06-20 16:38:30 -070015855 /* Issue Disconnect request */
15856 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053015857 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
15858 pAdapter->sessionId,
15859 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
15860 if (!HAL_STATUS_SUCCESS(hal_status)) {
15861 hddLog(LOGE,
15862 FL("sme_RoamDisconnect failed hal_status(%d)"),
15863 hal_status);
15864 return -EAGAIN;
15865 }
15866 status = wait_for_completion_timeout(
15867 &pAdapter->disconnect_comp_var,
15868 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
15869 if (!status) {
15870 hddLog(LOGE,
15871 FL("wait on disconnect_comp_var failed"));
15872 return -ETIMEDOUT;
15873 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015874
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015875 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015876 return 0;
15877}
15878
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015879static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15880 struct net_device *dev
15881 )
15882{
15883 int ret = 0;
15884
15885 vos_ssr_protect(__func__);
15886 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15887 vos_ssr_unprotect(__func__);
15888
15889 return ret;
15890}
15891
Jeff Johnson295189b2012-06-20 16:38:30 -070015892/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015893 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015894 * This function is used to set the phy parameters
15895 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15896 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015897static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015898 u32 changed)
15899{
15900 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15901 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015902 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015903
15904 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015905
15906 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015907 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15908 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015909
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015910 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015911 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015912 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015913 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015914 }
15915
Jeff Johnson295189b2012-06-20 16:38:30 -070015916 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15917 {
15918 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15919 WNI_CFG_RTS_THRESHOLD_STAMAX :
15920 wiphy->rts_threshold;
15921
15922 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015923 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015924 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015925 hddLog(VOS_TRACE_LEVEL_ERROR,
15926 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015927 __func__, rts_threshold);
15928 return -EINVAL;
15929 }
15930
15931 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15932 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015933 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015934 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015935 hddLog(VOS_TRACE_LEVEL_ERROR,
15936 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015937 __func__, rts_threshold);
15938 return -EIO;
15939 }
15940
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015941 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015942 rts_threshold);
15943 }
15944
15945 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15946 {
15947 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15948 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15949 wiphy->frag_threshold;
15950
15951 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015952 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015953 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015954 hddLog(VOS_TRACE_LEVEL_ERROR,
15955 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015956 frag_threshold);
15957 return -EINVAL;
15958 }
15959
15960 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15961 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015962 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015963 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015964 hddLog(VOS_TRACE_LEVEL_ERROR,
15965 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015966 __func__, frag_threshold);
15967 return -EIO;
15968 }
15969
15970 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15971 frag_threshold);
15972 }
15973
15974 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15975 || (changed & WIPHY_PARAM_RETRY_LONG))
15976 {
15977 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15978 wiphy->retry_short :
15979 wiphy->retry_long;
15980
15981 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15982 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15983 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015984 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015985 __func__, retry_value);
15986 return -EINVAL;
15987 }
15988
15989 if (changed & WIPHY_PARAM_RETRY_SHORT)
15990 {
15991 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15992 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015993 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015994 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015995 hddLog(VOS_TRACE_LEVEL_ERROR,
15996 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015997 __func__, retry_value);
15998 return -EIO;
15999 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016000 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016001 __func__, retry_value);
16002 }
16003 else if (changed & WIPHY_PARAM_RETRY_SHORT)
16004 {
16005 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
16006 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016007 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016008 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016009 hddLog(VOS_TRACE_LEVEL_ERROR,
16010 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016011 __func__, retry_value);
16012 return -EIO;
16013 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016014 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016015 __func__, retry_value);
16016 }
16017 }
16018
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016019 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016020 return 0;
16021}
16022
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016023static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
16024 u32 changed)
16025{
16026 int ret;
16027
16028 vos_ssr_protect(__func__);
16029 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
16030 vos_ssr_unprotect(__func__);
16031
16032 return ret;
16033}
16034
Jeff Johnson295189b2012-06-20 16:38:30 -070016035/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016036 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070016037 * This function is used to set the txpower
16038 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016039static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070016040#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16041 struct wireless_dev *wdev,
16042#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016043#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016044 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070016045#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016046 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070016047#endif
16048 int dbm)
16049{
16050 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016051 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016052 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
16053 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016054 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016055
16056 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016057
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016058 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16059 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
16060 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016061 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016062 if (0 != status)
16063 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016064 return status;
16065 }
16066
16067 hHal = pHddCtx->hHal;
16068
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016069 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
16070 dbm, ccmCfgSetCallback,
16071 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016072 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016073 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016074 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
16075 return -EIO;
16076 }
16077
16078 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
16079 dbm);
16080
16081 switch(type)
16082 {
16083 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
16084 /* Fall through */
16085 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
16086 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
16087 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016088 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
16089 __func__);
16090 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070016091 }
16092 break;
16093 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016094 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016095 __func__);
16096 return -EOPNOTSUPP;
16097 break;
16098 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016099 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
16100 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070016101 return -EIO;
16102 }
16103
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016104 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016105 return 0;
16106}
16107
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016108static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
16109#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16110 struct wireless_dev *wdev,
16111#endif
16112#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16113 enum tx_power_setting type,
16114#else
16115 enum nl80211_tx_power_setting type,
16116#endif
16117 int dbm)
16118{
16119 int ret;
16120 vos_ssr_protect(__func__);
16121 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
16122#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16123 wdev,
16124#endif
16125#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16126 type,
16127#else
16128 type,
16129#endif
16130 dbm);
16131 vos_ssr_unprotect(__func__);
16132
16133 return ret;
16134}
16135
Jeff Johnson295189b2012-06-20 16:38:30 -070016136/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016137 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070016138 * This function is used to read the txpower
16139 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016140static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070016141#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16142 struct wireless_dev *wdev,
16143#endif
16144 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070016145{
16146
16147 hdd_adapter_t *pAdapter;
16148 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016149 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016150
Jeff Johnsone7245742012-09-05 17:12:55 -070016151 ENTER();
16152
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016153 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016154 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016155 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016156 *dbm = 0;
16157 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016158 }
16159
Jeff Johnson295189b2012-06-20 16:38:30 -070016160 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
16161 if (NULL == pAdapter)
16162 {
16163 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
16164 return -ENOENT;
16165 }
16166
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016167 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16168 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
16169 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070016170 wlan_hdd_get_classAstats(pAdapter);
16171 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
16172
Jeff Johnsone7245742012-09-05 17:12:55 -070016173 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016174 return 0;
16175}
16176
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016177static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
16178#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16179 struct wireless_dev *wdev,
16180#endif
16181 int *dbm)
16182{
16183 int ret;
16184
16185 vos_ssr_protect(__func__);
16186 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
16187#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16188 wdev,
16189#endif
16190 dbm);
16191 vos_ssr_unprotect(__func__);
16192
16193 return ret;
16194}
16195
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016196static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016197#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16198 const u8* mac,
16199#else
16200 u8* mac,
16201#endif
16202 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070016203{
16204 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
16205 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16206 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053016207 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016208
16209 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
16210 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070016211
16212 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
16213 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
16214 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
16215 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
16216 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
16217 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
16218 tANI_U16 maxRate = 0;
16219 tANI_U16 myRate;
16220 tANI_U16 currentRate = 0;
16221 tANI_U8 maxSpeedMCS = 0;
16222 tANI_U8 maxMCSIdx = 0;
16223 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053016224 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070016225 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016226 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016227
Leo Chang6f8870f2013-03-26 18:11:36 -070016228#ifdef WLAN_FEATURE_11AC
16229 tANI_U32 vht_mcs_map;
16230 eDataRate11ACMaxMcs vhtMaxMcs;
16231#endif /* WLAN_FEATURE_11AC */
16232
Jeff Johnsone7245742012-09-05 17:12:55 -070016233 ENTER();
16234
Jeff Johnson295189b2012-06-20 16:38:30 -070016235 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
16236 (0 == ssidlen))
16237 {
16238 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
16239 " Invalid ssidlen, %d", __func__, ssidlen);
16240 /*To keep GUI happy*/
16241 return 0;
16242 }
16243
Mukul Sharma811205f2014-07-09 21:07:30 +053016244 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16245 {
16246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16247 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053016248 /* return a cached value */
16249 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053016250 return 0;
16251 }
16252
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016253 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016254 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016255 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016256 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016257 }
16258
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053016259 wlan_hdd_get_station_stats(pAdapter);
16260 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016261
Kiet Lam3b17fc82013-09-27 05:24:08 +053016262 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
16263 sinfo->filled |= STATION_INFO_SIGNAL;
16264
c_hpothu09f19542014-05-30 21:53:31 +053016265 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053016266 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
16267 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053016268 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053016269 {
16270 rate_flags = pAdapter->maxRateFlags;
16271 }
c_hpothu44ff4e02014-05-08 00:13:57 +053016272
Jeff Johnson295189b2012-06-20 16:38:30 -070016273 //convert to the UI units of 100kbps
16274 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
16275
16276#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070016277 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 -070016278 sinfo->signal,
16279 pCfg->reportMaxLinkSpeed,
16280 myRate,
16281 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016282 (int) pCfg->linkSpeedRssiMid,
16283 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070016284 (int) rate_flags,
16285 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070016286#endif //LINKSPEED_DEBUG_ENABLED
16287
16288 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
16289 {
16290 // we do not want to necessarily report the current speed
16291 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
16292 {
16293 // report the max possible speed
16294 rssidx = 0;
16295 }
16296 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
16297 {
16298 // report the max possible speed with RSSI scaling
16299 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
16300 {
16301 // report the max possible speed
16302 rssidx = 0;
16303 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016304 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070016305 {
16306 // report middle speed
16307 rssidx = 1;
16308 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016309 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
16310 {
16311 // report middle speed
16312 rssidx = 2;
16313 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016314 else
16315 {
16316 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016317 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070016318 }
16319 }
16320 else
16321 {
16322 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
16323 hddLog(VOS_TRACE_LEVEL_ERROR,
16324 "%s: Invalid value for reportMaxLinkSpeed: %u",
16325 __func__, pCfg->reportMaxLinkSpeed);
16326 rssidx = 0;
16327 }
16328
16329 maxRate = 0;
16330
16331 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016332 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
16333 OperationalRates, &ORLeng))
16334 {
16335 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16336 /*To keep GUI happy*/
16337 return 0;
16338 }
16339
Jeff Johnson295189b2012-06-20 16:38:30 -070016340 for (i = 0; i < ORLeng; i++)
16341 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016342 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016343 {
16344 /* Validate Rate Set */
16345 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
16346 {
16347 currentRate = supported_data_rate[j].supported_rate[rssidx];
16348 break;
16349 }
16350 }
16351 /* Update MAX rate */
16352 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16353 }
16354
16355 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016356 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
16357 ExtendedRates, &ERLeng))
16358 {
16359 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16360 /*To keep GUI happy*/
16361 return 0;
16362 }
16363
Jeff Johnson295189b2012-06-20 16:38:30 -070016364 for (i = 0; i < ERLeng; i++)
16365 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016366 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016367 {
16368 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
16369 {
16370 currentRate = supported_data_rate[j].supported_rate[rssidx];
16371 break;
16372 }
16373 }
16374 /* Update MAX rate */
16375 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16376 }
c_hpothu79aab322014-07-14 21:11:01 +053016377
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016378 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053016379 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016380 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053016381 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070016382 {
c_hpothu79aab322014-07-14 21:11:01 +053016383 if (rate_flags & eHAL_TX_RATE_VHT80)
16384 mode = 2;
16385 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
16386 mode = 1;
16387 else
16388 mode = 0;
16389
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016390 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
16391 MCSRates, &MCSLeng))
16392 {
16393 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16394 /*To keep GUI happy*/
16395 return 0;
16396 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016397 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070016398#ifdef WLAN_FEATURE_11AC
16399 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016400 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070016401 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016402 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016403 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070016404 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070016405 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016406 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016407 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016408 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070016409 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016410 maxMCSIdx = 7;
16411 }
16412 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
16413 {
16414 maxMCSIdx = 8;
16415 }
16416 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
16417 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016418 //VHT20 is supporting 0~8
16419 if (rate_flags & eHAL_TX_RATE_VHT20)
16420 maxMCSIdx = 8;
16421 else
16422 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070016423 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016424
c_hpothu79aab322014-07-14 21:11:01 +053016425 if (0 != rssidx)/*check for scaled */
16426 {
16427 //get middle rate MCS index if rssi=1/2
16428 for (i=0; i <= maxMCSIdx; i++)
16429 {
16430 if (sinfo->signal <= rssiMcsTbl[mode][i])
16431 {
16432 maxMCSIdx = i;
16433 break;
16434 }
16435 }
16436 }
16437
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016438 if (rate_flags & eHAL_TX_RATE_VHT80)
16439 {
16440 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
16441 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
16442 }
16443 else if (rate_flags & eHAL_TX_RATE_VHT40)
16444 {
16445 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
16446 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
16447 }
16448 else if (rate_flags & eHAL_TX_RATE_VHT20)
16449 {
16450 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
16451 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
16452 }
16453
Leo Chang6f8870f2013-03-26 18:11:36 -070016454 maxSpeedMCS = 1;
16455 if (currentRate > maxRate)
16456 {
16457 maxRate = currentRate;
16458 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016459
Leo Chang6f8870f2013-03-26 18:11:36 -070016460 }
16461 else
16462#endif /* WLAN_FEATURE_11AC */
16463 {
16464 if (rate_flags & eHAL_TX_RATE_HT40)
16465 {
16466 rateFlag |= 1;
16467 }
16468 if (rate_flags & eHAL_TX_RATE_SGI)
16469 {
16470 rateFlag |= 2;
16471 }
16472
Girish Gowli01abcee2014-07-31 20:18:55 +053016473 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053016474 if (rssidx == 1 || rssidx == 2)
16475 {
16476 //get middle rate MCS index if rssi=1/2
16477 for (i=0; i <= 7; i++)
16478 {
16479 if (sinfo->signal <= rssiMcsTbl[mode][i])
16480 {
16481 temp = i+1;
16482 break;
16483 }
16484 }
16485 }
c_hpothu79aab322014-07-14 21:11:01 +053016486
16487 for (i = 0; i < MCSLeng; i++)
16488 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016489 for (j = 0; j < temp; j++)
16490 {
16491 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
16492 {
16493 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016494 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016495 break;
16496 }
16497 }
16498 if ((j < temp) && (currentRate > maxRate))
16499 {
16500 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070016501 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016502 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016503 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016504 }
16505 }
16506
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016507 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
16508 {
16509 maxRate = myRate;
16510 maxSpeedMCS = 1;
16511 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16512 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016513 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053016514 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070016515 {
16516 maxRate = myRate;
16517 if (rate_flags & eHAL_TX_RATE_LEGACY)
16518 {
16519 maxSpeedMCS = 0;
16520 }
16521 else
16522 {
16523 maxSpeedMCS = 1;
16524 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16525 }
16526 }
16527
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016528 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070016529 {
16530 sinfo->txrate.legacy = maxRate;
16531#ifdef LINKSPEED_DEBUG_ENABLED
16532 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
16533#endif //LINKSPEED_DEBUG_ENABLED
16534 }
16535 else
16536 {
16537 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070016538#ifdef WLAN_FEATURE_11AC
16539 sinfo->txrate.nss = 1;
16540 if (rate_flags & eHAL_TX_RATE_VHT80)
16541 {
16542 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016543 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070016544 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016545 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070016546 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016547 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16548 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16549 }
16550 else if (rate_flags & eHAL_TX_RATE_VHT20)
16551 {
16552 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16553 }
16554#endif /* WLAN_FEATURE_11AC */
16555 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
16556 {
16557 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16558 if (rate_flags & eHAL_TX_RATE_HT40)
16559 {
16560 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16561 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016562 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016563 if (rate_flags & eHAL_TX_RATE_SGI)
16564 {
16565 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16566 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016567
Jeff Johnson295189b2012-06-20 16:38:30 -070016568#ifdef LINKSPEED_DEBUG_ENABLED
16569 pr_info("Reporting MCS rate %d flags %x\n",
16570 sinfo->txrate.mcs,
16571 sinfo->txrate.flags );
16572#endif //LINKSPEED_DEBUG_ENABLED
16573 }
16574 }
16575 else
16576 {
16577 // report current rate instead of max rate
16578
16579 if (rate_flags & eHAL_TX_RATE_LEGACY)
16580 {
16581 //provide to the UI in units of 100kbps
16582 sinfo->txrate.legacy = myRate;
16583#ifdef LINKSPEED_DEBUG_ENABLED
16584 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
16585#endif //LINKSPEED_DEBUG_ENABLED
16586 }
16587 else
16588 {
16589 //must be MCS
16590 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016591#ifdef WLAN_FEATURE_11AC
16592 sinfo->txrate.nss = 1;
16593 if (rate_flags & eHAL_TX_RATE_VHT80)
16594 {
16595 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16596 }
16597 else
16598#endif /* WLAN_FEATURE_11AC */
16599 {
16600 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16601 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016602 if (rate_flags & eHAL_TX_RATE_SGI)
16603 {
16604 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16605 }
16606 if (rate_flags & eHAL_TX_RATE_HT40)
16607 {
16608 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16609 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016610#ifdef WLAN_FEATURE_11AC
16611 else if (rate_flags & eHAL_TX_RATE_VHT80)
16612 {
16613 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
16614 }
16615#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070016616#ifdef LINKSPEED_DEBUG_ENABLED
16617 pr_info("Reporting actual MCS rate %d flags %x\n",
16618 sinfo->txrate.mcs,
16619 sinfo->txrate.flags );
16620#endif //LINKSPEED_DEBUG_ENABLED
16621 }
16622 }
16623 sinfo->filled |= STATION_INFO_TX_BITRATE;
16624
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016625 sinfo->tx_packets =
16626 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
16627 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
16628 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
16629 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
16630
16631 sinfo->tx_retries =
16632 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
16633 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
16634 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
16635 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
16636
16637 sinfo->tx_failed =
16638 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
16639 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
16640 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
16641 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
16642
16643 sinfo->filled |=
16644 STATION_INFO_TX_PACKETS |
16645 STATION_INFO_TX_RETRIES |
16646 STATION_INFO_TX_FAILED;
16647
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053016648 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
16649 sinfo->filled |= STATION_INFO_RX_PACKETS;
16650
16651 if (rate_flags & eHAL_TX_RATE_LEGACY)
16652 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
16653 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
16654 sinfo->rx_packets);
16655 else
16656 hddLog(LOG1,
16657 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
16658 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
16659 sinfo->tx_packets, sinfo->rx_packets);
16660
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016661 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16662 TRACE_CODE_HDD_CFG80211_GET_STA,
16663 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016664 EXIT();
16665 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070016666}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016667#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16668static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16669 const u8* mac, struct station_info *sinfo)
16670#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016671static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16672 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016673#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016674{
16675 int ret;
16676
16677 vos_ssr_protect(__func__);
16678 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
16679 vos_ssr_unprotect(__func__);
16680
16681 return ret;
16682}
16683
16684static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070016685 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070016686{
16687 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016688 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016689 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016690 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016691
Jeff Johnsone7245742012-09-05 17:12:55 -070016692 ENTER();
16693
Jeff Johnson295189b2012-06-20 16:38:30 -070016694 if (NULL == pAdapter)
16695 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016696 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016697 return -ENODEV;
16698 }
16699
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016700 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16701 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
16702 pAdapter->sessionId, timeout));
16703
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016704 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016705 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016706 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016707 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016708 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016709 }
16710
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016711 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
16712 (TRUE == pHddCtx->hdd_wlan_suspended) &&
16713 (pHddCtx->cfg_ini->fhostArpOffload) &&
16714 (eConnectionState_Associated ==
16715 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
16716 {
Amar Singhald53568e2013-09-26 11:03:45 -070016717
16718 hddLog(VOS_TRACE_LEVEL_INFO,
16719 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053016720 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016721 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16722 {
16723 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016724 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016725 __func__, vos_status);
16726 }
16727 }
16728
Jeff Johnson295189b2012-06-20 16:38:30 -070016729 /**The get power cmd from the supplicant gets updated by the nl only
16730 *on successful execution of the function call
16731 *we are oppositely mapped w.r.t mode in the driver
16732 **/
16733 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
16734
16735 if (VOS_STATUS_E_FAILURE == vos_status)
16736 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16738 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016739 return -EINVAL;
16740 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016741 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016742 return 0;
16743}
16744
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016745static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
16746 struct net_device *dev, bool mode, int timeout)
16747{
16748 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016749
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016750 vos_ssr_protect(__func__);
16751 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
16752 vos_ssr_unprotect(__func__);
16753
16754 return ret;
16755}
Sushant Kaushik084f6592015-09-10 13:11:56 +053016756
Jeff Johnson295189b2012-06-20 16:38:30 -070016757#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016758static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
16759 struct net_device *netdev,
16760 u8 key_index)
16761{
16762 ENTER();
16763 return 0;
16764}
16765
Jeff Johnson295189b2012-06-20 16:38:30 -070016766static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016767 struct net_device *netdev,
16768 u8 key_index)
16769{
16770 int ret;
16771 vos_ssr_protect(__func__);
16772 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
16773 vos_ssr_unprotect(__func__);
16774 return ret;
16775}
16776#endif //LINUX_VERSION_CODE
16777
16778#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16779static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16780 struct net_device *dev,
16781 struct ieee80211_txq_params *params)
16782{
16783 ENTER();
16784 return 0;
16785}
16786#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16787static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16788 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016789{
Jeff Johnsone7245742012-09-05 17:12:55 -070016790 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070016791 return 0;
16792}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016793#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070016794
16795#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16796static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016797 struct net_device *dev,
16798 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016799{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016800 int ret;
16801
16802 vos_ssr_protect(__func__);
16803 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
16804 vos_ssr_unprotect(__func__);
16805 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016806}
16807#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16808static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
16809 struct ieee80211_txq_params *params)
16810{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016811 int ret;
16812
16813 vos_ssr_protect(__func__);
16814 ret = __wlan_hdd_set_txq_params(wiphy, params);
16815 vos_ssr_unprotect(__func__);
16816 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016817}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016818#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016819
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016820static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016821 struct net_device *dev,
16822 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070016823{
16824 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016825 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016826 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016827 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016828 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016829 v_CONTEXT_t pVosContext = NULL;
16830 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016831
Jeff Johnsone7245742012-09-05 17:12:55 -070016832 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016833
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016834 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070016835 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016836 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016837 return -EINVAL;
16838 }
16839
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016840 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16841 TRACE_CODE_HDD_CFG80211_DEL_STA,
16842 pAdapter->sessionId, pAdapter->device_mode));
16843
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016844 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16845 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016846 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016847 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016848 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016849 }
16850
Jeff Johnson295189b2012-06-20 16:38:30 -070016851 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016852 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016853 )
16854 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016855 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
16856 pSapCtx = VOS_GET_SAP_CB(pVosContext);
16857 if(pSapCtx == NULL){
16858 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16859 FL("psapCtx is NULL"));
16860 return -ENOENT;
16861 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016862 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070016863 {
16864 v_U16_t i;
16865 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
16866 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016867 if ((pSapCtx->aStaInfo[i].isUsed) &&
16868 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070016869 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016870 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016871 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016872 ETHER_ADDR_LEN);
16873
Jeff Johnson295189b2012-06-20 16:38:30 -070016874 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016875 "%s: Delete STA with MAC::"
16876 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016877 __func__,
16878 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
16879 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070016880 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016881 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016882 }
16883 }
16884 }
16885 else
16886 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016887
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016888 vos_status = hdd_softap_GetStaId(pAdapter,
16889 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016890 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16891 {
16892 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016893 "%s: Skip this DEL STA as this is not used::"
16894 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016895 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016896 return -ENOENT;
16897 }
16898
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016899 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016900 {
16901 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016902 "%s: Skip this DEL STA as deauth is in progress::"
16903 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016904 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016905 return -ENOENT;
16906 }
16907
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016908 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016909
Jeff Johnson295189b2012-06-20 16:38:30 -070016910 hddLog(VOS_TRACE_LEVEL_INFO,
16911 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016912 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016913 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016914 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016915
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016916 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016917 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16918 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016919 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016920 hddLog(VOS_TRACE_LEVEL_INFO,
16921 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016922 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016923 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016924 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016925 return -ENOENT;
16926 }
16927
Jeff Johnson295189b2012-06-20 16:38:30 -070016928 }
16929 }
16930
16931 EXIT();
16932
16933 return 0;
16934}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016935
16936#ifdef CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053016937int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016938 struct net_device *dev,
16939 struct station_del_parameters *param)
16940#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016941#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053016942int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016943 struct net_device *dev, const u8 *mac)
16944#else
Kapil Gupta137ef892016-12-13 19:38:00 +053016945int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016946 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016947#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016948#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016949{
16950 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016951 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016952
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016953 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016954
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016955#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016956 if (NULL == param) {
16957 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016958 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016959 return -EINVAL;
16960 }
16961
16962 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16963 param->subtype, &delStaParams);
16964
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016965#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016966 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016967 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016968#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016969 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16970
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016971 vos_ssr_unprotect(__func__);
16972
16973 return ret;
16974}
16975
16976static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016977 struct net_device *dev,
16978#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16979 const u8 *mac,
16980#else
16981 u8 *mac,
16982#endif
16983 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016984{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016985 hdd_adapter_t *pAdapter;
16986 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016987 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016988#ifdef FEATURE_WLAN_TDLS
16989 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016990
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016991 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016992
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016993 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16994 if (NULL == pAdapter)
16995 {
16996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16997 "%s: Adapter is NULL",__func__);
16998 return -EINVAL;
16999 }
17000 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17001 status = wlan_hdd_validate_context(pHddCtx);
17002 if (0 != status)
17003 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017004 return status;
17005 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017006
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017007 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17008 TRACE_CODE_HDD_CFG80211_ADD_STA,
17009 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017010 mask = params->sta_flags_mask;
17011
17012 set = params->sta_flags_set;
17013
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017014 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017015 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
17016 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017017
17018 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
17019 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080017020 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017021 }
17022 }
17023#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017024 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017025 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017026}
17027
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017028#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17029static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
17030 struct net_device *dev, const u8 *mac,
17031 struct station_parameters *params)
17032#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017033static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
17034 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017035#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017036{
17037 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017038
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017039 vos_ssr_protect(__func__);
17040 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
17041 vos_ssr_unprotect(__func__);
17042
17043 return ret;
17044}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017045#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070017046
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017047static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070017048 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017049{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017050 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17051 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017052 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017053 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017054 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017055 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070017056
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017057 ENTER();
17058
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017059 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017060 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017061 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017062 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017063 return -EINVAL;
17064 }
17065
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017066 if (!pmksa) {
17067 hddLog(LOGE, FL("pmksa is NULL"));
17068 return -EINVAL;
17069 }
17070
17071 if (!pmksa->bssid || !pmksa->pmkid) {
17072 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
17073 pmksa->bssid, pmksa->pmkid);
17074 return -EINVAL;
17075 }
17076
17077 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
17078 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17079
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017080 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17081 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017082 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017083 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017084 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017085 }
17086
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017087 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017088 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17089
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017090 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
17091 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017092
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017093 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017094 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017095 &pmk_id, 1, FALSE);
17096
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017097 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17098 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
17099 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017100
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017101 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017102 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017103}
17104
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017105static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
17106 struct cfg80211_pmksa *pmksa)
17107{
17108 int ret;
17109
17110 vos_ssr_protect(__func__);
17111 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
17112 vos_ssr_unprotect(__func__);
17113
17114 return ret;
17115}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017116
Wilson Yang6507c4e2013-10-01 20:11:19 -070017117
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017118static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070017119 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017120{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017121 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17122 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017123 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017124 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017125
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017126 ENTER();
17127
Wilson Yang6507c4e2013-10-01 20:11:19 -070017128 /* Validate pAdapter */
17129 if (NULL == pAdapter)
17130 {
17131 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
17132 return -EINVAL;
17133 }
17134
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017135 if (!pmksa) {
17136 hddLog(LOGE, FL("pmksa is NULL"));
17137 return -EINVAL;
17138 }
17139
17140 if (!pmksa->bssid) {
17141 hddLog(LOGE, FL("pmksa->bssid is NULL"));
17142 return -EINVAL;
17143 }
17144
Kiet Lam98c46a12014-10-31 15:34:57 -070017145 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
17146 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17147
Wilson Yang6507c4e2013-10-01 20:11:19 -070017148 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17149 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017150 if (0 != status)
17151 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017152 return status;
17153 }
17154
17155 /*Retrieve halHandle*/
17156 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17157
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017158 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17159 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
17160 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017161 /* Delete the PMKID CSR cache */
17162 if (eHAL_STATUS_SUCCESS !=
17163 sme_RoamDelPMKIDfromCache(halHandle,
17164 pAdapter->sessionId, pmksa->bssid, FALSE)) {
17165 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
17166 MAC_ADDR_ARRAY(pmksa->bssid));
17167 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017168 }
17169
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017170 EXIT();
17171 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017172}
17173
Wilson Yang6507c4e2013-10-01 20:11:19 -070017174
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017175static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
17176 struct cfg80211_pmksa *pmksa)
17177{
17178 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017179
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017180 vos_ssr_protect(__func__);
17181 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
17182 vos_ssr_unprotect(__func__);
17183
17184 return ret;
17185
17186}
17187
17188static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017189{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017190 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17191 tHalHandle halHandle;
17192 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017193 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017194
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017195 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070017196
17197 /* Validate pAdapter */
17198 if (NULL == pAdapter)
17199 {
17200 hddLog(VOS_TRACE_LEVEL_ERROR,
17201 "%s: Invalid Adapter" ,__func__);
17202 return -EINVAL;
17203 }
17204
17205 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17206 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017207 if (0 != status)
17208 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017209 return status;
17210 }
17211
17212 /*Retrieve halHandle*/
17213 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17214
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017215 /* Flush the PMKID cache in CSR */
17216 if (eHAL_STATUS_SUCCESS !=
17217 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
17218 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
17219 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017220 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017221 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080017222 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017223}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017224
17225static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
17226{
17227 int ret;
17228
17229 vos_ssr_protect(__func__);
17230 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
17231 vos_ssr_unprotect(__func__);
17232
17233 return ret;
17234}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017235#endif
17236
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017237#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017238static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17239 struct net_device *dev,
17240 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017241{
17242 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17243 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017244 hdd_context_t *pHddCtx;
17245 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017246
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017247 ENTER();
17248
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017249 if (NULL == pAdapter)
17250 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017251 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017252 return -ENODEV;
17253 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017254 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17255 ret = wlan_hdd_validate_context(pHddCtx);
17256 if (0 != ret)
17257 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017258 return ret;
17259 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017260 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017261 if (NULL == pHddStaCtx)
17262 {
17263 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
17264 return -EINVAL;
17265 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017266
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017267 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17268 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
17269 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017270 // Added for debug on reception of Re-assoc Req.
17271 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
17272 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017273 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017274 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080017275 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017276 }
17277
17278#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080017279 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017280 ftie->ie_len);
17281#endif
17282
17283 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053017284 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
17285 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017286 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017287
17288 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017289 return 0;
17290}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017291
17292static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17293 struct net_device *dev,
17294 struct cfg80211_update_ft_ies_params *ftie)
17295{
17296 int ret;
17297
17298 vos_ssr_protect(__func__);
17299 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
17300 vos_ssr_unprotect(__func__);
17301
17302 return ret;
17303}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017304#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017305
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017306#ifdef FEATURE_WLAN_SCAN_PNO
17307
17308void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
17309 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
17310{
17311 int ret;
17312 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
17313 hdd_context_t *pHddCtx;
17314
Nirav Shah80830bf2013-12-31 16:35:12 +053017315 ENTER();
17316
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017317 if (NULL == pAdapter)
17318 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053017319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017320 "%s: HDD adapter is Null", __func__);
17321 return ;
17322 }
17323
17324 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17325 if (NULL == pHddCtx)
17326 {
17327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17328 "%s: HDD context is Null!!!", __func__);
17329 return ;
17330 }
17331
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017332 spin_lock(&pHddCtx->schedScan_lock);
17333 if (TRUE == pHddCtx->isWiphySuspended)
17334 {
17335 pHddCtx->isSchedScanUpdatePending = TRUE;
17336 spin_unlock(&pHddCtx->schedScan_lock);
17337 hddLog(VOS_TRACE_LEVEL_INFO,
17338 "%s: Update cfg80211 scan database after it resume", __func__);
17339 return ;
17340 }
17341 spin_unlock(&pHddCtx->schedScan_lock);
17342
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017343 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
17344
17345 if (0 > ret)
17346 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053017347 else
17348 {
17349 /* Acquire wakelock to handle the case where APP's tries to suspend
17350 * immediatly after the driver gets connect request(i.e after pno)
17351 * from supplicant, this result in app's is suspending and not able
17352 * to process the connect request to AP */
17353 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
17354 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017355 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017356 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17357 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017358}
17359
17360/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017361 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017362 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017363 */
17364static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
17365{
17366 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
17367 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017368 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017369 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17370 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053017371
17372 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
17373 {
17374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17375 "%s: PNO is allowed only in STA interface", __func__);
17376 return eHAL_STATUS_FAILURE;
17377 }
17378
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017379 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
17380
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017381 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053017382 * active sessions. PNO is allowed only in case when sap session
17383 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017384 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017385 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
17386 {
17387 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017388 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017389
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017390 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
17391 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
17392 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
17393 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053017394 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
17395 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053017396 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017397 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017398 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017399 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017400 }
17401 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17402 pAdapterNode = pNext;
17403 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017404 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017405}
17406
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017407void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
17408{
17409 hdd_adapter_t *pAdapter = callbackContext;
17410 hdd_context_t *pHddCtx;
17411
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017412 ENTER();
17413
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017414 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
17415 {
17416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17417 FL("Invalid adapter or adapter has invalid magic"));
17418 return;
17419 }
17420
17421 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17422 if (0 != wlan_hdd_validate_context(pHddCtx))
17423 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017424 return;
17425 }
17426
c_hpothub53c45d2014-08-18 16:53:14 +053017427 if (VOS_STATUS_SUCCESS != status)
17428 {
17429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017430 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053017431 pHddCtx->isPnoEnable = FALSE;
17432 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017433
17434 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
17435 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017436 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017437}
17438
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017439#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
17440 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
17441/**
17442 * hdd_config_sched_scan_plan() - configures the sched scan plans
17443 * from the framework.
17444 * @pno_req: pointer to PNO scan request
17445 * @request: pointer to scan request from framework
17446 *
17447 * Return: None
17448 */
17449static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
17450 struct cfg80211_sched_scan_request *request,
17451 hdd_context_t *hdd_ctx)
17452{
17453 v_U32_t i = 0;
17454
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017455 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017456 for (i = 0; i < request->n_scan_plans; i++)
17457 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017458 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
17459 request->scan_plans[i].iterations;
17460 pno_req->scanTimers.aTimerValues[i].uTimerValue =
17461 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017462 }
17463}
17464#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017465static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017466 struct cfg80211_sched_scan_request *request,
17467 hdd_context_t *hdd_ctx)
17468{
17469 v_U32_t i, temp_int;
17470 /* Driver gets only one time interval which is hardcoded in
17471 * supplicant for 10000ms. Taking power consumption into account 6
17472 * timers will be used, Timervalue is increased exponentially
17473 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
17474 * timer is configurable through INI param gPNOScanTimerRepeatValue.
17475 * If it is set to 0 only one timer will be used and PNO scan cycle
17476 * will be repeated after each interval specified by supplicant
17477 * till PNO is disabled.
17478 */
17479 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017480 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017481 HDD_PNO_SCAN_TIMERS_SET_ONE;
17482 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017483 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017484 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
17485
17486 temp_int = (request->interval)/1000;
17487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17488 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
17489 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017490 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017491 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017492 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017493 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017494 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017495 temp_int *= 2;
17496 }
17497 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017498 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017499}
17500#endif
17501
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017502/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017503 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
17504 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017505 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017506static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017507 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17508{
17509 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017510 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017511 hdd_context_t *pHddCtx;
17512 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017513 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053017514 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
17515 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017516 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17517 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017518 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017519 hdd_config_t *pConfig = NULL;
17520 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017521
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017522 ENTER();
17523
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017524 if (NULL == pAdapter)
17525 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017526 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017527 "%s: HDD adapter is Null", __func__);
17528 return -ENODEV;
17529 }
17530
17531 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017532 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017533
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017534 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017535 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017536 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017537 }
17538
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017539 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017540 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17541 if (NULL == hHal)
17542 {
17543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17544 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017545 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017546 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017547 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17548 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
17549 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053017550 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053017551 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053017552 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053017553 {
17554 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17555 "%s: aborting the existing scan is unsuccessfull", __func__);
17556 return -EBUSY;
17557 }
17558
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017559 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017560 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017562 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017563 return -EBUSY;
17564 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017565
c_hpothu37f21312014-04-09 21:49:54 +053017566 if (TRUE == pHddCtx->isPnoEnable)
17567 {
17568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17569 FL("already PNO is enabled"));
17570 return -EBUSY;
17571 }
c_hpothu225aa7c2014-10-22 17:45:13 +053017572
17573 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
17574 {
17575 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17576 "%s: abort ROC failed ", __func__);
17577 return -EBUSY;
17578 }
17579
c_hpothu37f21312014-04-09 21:49:54 +053017580 pHddCtx->isPnoEnable = TRUE;
17581
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017582 pnoRequest.enable = 1; /*Enable PNO */
17583 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017584
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017585 if (( !pnoRequest.ucNetworksCount ) ||
17586 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017587 {
17588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017589 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017590 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017591 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017592 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017593 goto error;
17594 }
17595
17596 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
17597 {
17598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017599 "%s: Incorrect number of channels %d",
17600 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017601 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017602 goto error;
17603 }
17604
17605 /* Framework provides one set of channels(all)
17606 * common for all saved profile */
17607 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17608 channels_allowed, &num_channels_allowed))
17609 {
17610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17611 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017612 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017613 goto error;
17614 }
17615 /* Checking each channel against allowed channel list */
17616 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053017617 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017618 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017619 char chList [(request->n_channels*5)+1];
17620 int len;
17621 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017622 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017623 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017624 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017625 if (request->channels[i]->hw_value == channels_allowed[indx])
17626 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017627 if ((!pConfig->enableDFSPnoChnlScan) &&
17628 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
17629 {
17630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17631 "%s : Dropping DFS channel : %d",
17632 __func__,channels_allowed[indx]);
17633 num_ignore_dfs_ch++;
17634 break;
17635 }
17636
Nirav Shah80830bf2013-12-31 16:35:12 +053017637 valid_ch[num_ch++] = request->channels[i]->hw_value;
17638 len += snprintf(chList+len, 5, "%d ",
17639 request->channels[i]->hw_value);
17640 break ;
17641 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017642 }
17643 }
Nirav Shah80830bf2013-12-31 16:35:12 +053017644 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017645
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017646 /*If all channels are DFS and dropped, then ignore the PNO request*/
17647 if (num_ignore_dfs_ch == request->n_channels)
17648 {
17649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17650 "%s : All requested channels are DFS channels", __func__);
17651 ret = -EINVAL;
17652 goto error;
17653 }
17654 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017655
17656 pnoRequest.aNetworks =
17657 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17658 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017659 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017660 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17661 FL("failed to allocate memory aNetworks %u"),
17662 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17663 goto error;
17664 }
17665 vos_mem_zero(pnoRequest.aNetworks,
17666 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17667
17668 /* Filling per profile params */
17669 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
17670 {
17671 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017672 request->match_sets[i].ssid.ssid_len;
17673
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017674 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
17675 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017676 {
17677 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017678 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017679 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017680 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017681 goto error;
17682 }
17683
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017684 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017685 request->match_sets[i].ssid.ssid,
17686 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17688 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017689 i, pnoRequest.aNetworks[i].ssId.ssId);
17690 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
17691 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
17692 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017693
17694 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017695 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
17696 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017697
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017698 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017699 }
17700
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017701 for (i = 0; i < request->n_ssids; i++)
17702 {
17703 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017704 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017705 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017706 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017707 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017708 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017709 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017710 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017711 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017712 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017713 break;
17714 }
17715 j++;
17716 }
17717 }
17718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17719 "Number of hidden networks being Configured = %d",
17720 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080017722 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017723
17724 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17725 if (pnoRequest.p24GProbeTemplate == NULL)
17726 {
17727 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17728 FL("failed to allocate memory p24GProbeTemplate %u"),
17729 SIR_PNO_MAX_PB_REQ_SIZE);
17730 goto error;
17731 }
17732
17733 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17734 if (pnoRequest.p5GProbeTemplate == NULL)
17735 {
17736 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17737 FL("failed to allocate memory p5GProbeTemplate %u"),
17738 SIR_PNO_MAX_PB_REQ_SIZE);
17739 goto error;
17740 }
17741
17742 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17743 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17744
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053017745 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
17746 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017747 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017748 pnoRequest.us24GProbeTemplateLen = request->ie_len;
17749 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
17750 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017751
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017752 pnoRequest.us5GProbeTemplateLen = request->ie_len;
17753 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
17754 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017755 }
17756
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017757 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017758
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017759 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017760
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017761 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017762 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17763 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017764 pAdapter->pno_req_status = 0;
17765
Nirav Shah80830bf2013-12-31 16:35:12 +053017766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17767 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017768 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
17769 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053017770
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017771 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017772 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017773 hdd_cfg80211_sched_scan_done_callback, pAdapter);
17774 if (eHAL_STATUS_SUCCESS != status)
17775 {
17776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017777 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017778 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017779 goto error;
17780 }
17781
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017782 ret = wait_for_completion_timeout(
17783 &pAdapter->pno_comp_var,
17784 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17785 if (0 >= ret)
17786 {
17787 // Did not receive the response for PNO enable in time.
17788 // Assuming the PNO enable was success.
17789 // Returning error from here, because we timeout, results
17790 // in side effect of Wifi (Wifi Setting) not to work.
17791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17792 FL("Timed out waiting for PNO to be Enabled"));
17793 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017794 }
17795
17796 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053017797 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017798
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017799error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17801 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053017802 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017803 if (pnoRequest.aNetworks)
17804 vos_mem_free(pnoRequest.aNetworks);
17805 if (pnoRequest.p24GProbeTemplate)
17806 vos_mem_free(pnoRequest.p24GProbeTemplate);
17807 if (pnoRequest.p5GProbeTemplate)
17808 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017809
17810 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017811 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017812}
17813
17814/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017815 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
17816 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017817 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017818static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
17819 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17820{
17821 int ret;
17822
17823 vos_ssr_protect(__func__);
17824 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
17825 vos_ssr_unprotect(__func__);
17826
17827 return ret;
17828}
17829
17830/*
17831 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
17832 * Function to disable PNO
17833 */
17834static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017835 struct net_device *dev)
17836{
17837 eHalStatus status = eHAL_STATUS_FAILURE;
17838 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17839 hdd_context_t *pHddCtx;
17840 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017841 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017842 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017843
17844 ENTER();
17845
17846 if (NULL == pAdapter)
17847 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017849 "%s: HDD adapter is Null", __func__);
17850 return -ENODEV;
17851 }
17852
17853 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017854
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017855 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017856 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017858 "%s: HDD context is Null", __func__);
17859 return -ENODEV;
17860 }
17861
17862 /* The return 0 is intentional when isLogpInProgress and
17863 * isLoadUnloadInProgress. We did observe a crash due to a return of
17864 * failure in sched_scan_stop , especially for a case where the unload
17865 * of the happens at the same time. The function __cfg80211_stop_sched_scan
17866 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
17867 * success. If it returns a failure , then its next invocation due to the
17868 * clean up of the second interface will have the dev pointer corresponding
17869 * to the first one leading to a crash.
17870 */
17871 if (pHddCtx->isLogpInProgress)
17872 {
17873 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17874 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053017875 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017876 return ret;
17877 }
17878
Mihir Shete18156292014-03-11 15:38:30 +053017879 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017880 {
17881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17882 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17883 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017884 }
17885
17886 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17887 if (NULL == hHal)
17888 {
17889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17890 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017891 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017892 }
17893
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017894 pnoRequest.enable = 0; /* Disable PNO */
17895 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017896
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017897 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17898 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
17899 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017900
17901 INIT_COMPLETION(pAdapter->pno_comp_var);
17902 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17903 pnoRequest.callbackContext = pAdapter;
17904 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017905 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017906 pAdapter->sessionId,
17907 NULL, pAdapter);
17908 if (eHAL_STATUS_SUCCESS != status)
17909 {
17910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17911 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017912 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017913 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017914 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017915 ret = wait_for_completion_timeout(
17916 &pAdapter->pno_comp_var,
17917 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17918 if (0 >= ret)
17919 {
17920 // Did not receive the response for PNO disable in time.
17921 // Assuming the PNO disable was success.
17922 // Returning error from here, because we timeout, results
17923 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053017924 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017925 FL("Timed out waiting for PNO to be disabled"));
17926 ret = 0;
17927 }
17928
17929 ret = pAdapter->pno_req_status;
17930 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017931
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017932error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017933 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017934 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017935
17936 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017937 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017938}
17939
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017940/*
17941 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
17942 * NL interface to disable PNO
17943 */
17944static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
17945 struct net_device *dev)
17946{
17947 int ret;
17948
17949 vos_ssr_protect(__func__);
17950 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
17951 vos_ssr_unprotect(__func__);
17952
17953 return ret;
17954}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017955#endif /*FEATURE_WLAN_SCAN_PNO*/
17956
17957
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017958#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017959#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017960static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17961 struct net_device *dev,
17962 u8 *peer, u8 action_code,
17963 u8 dialog_token,
17964 u16 status_code, u32 peer_capability,
17965 const u8 *buf, size_t len)
17966#else /* TDLS_MGMT_VERSION2 */
17967#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17968static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17969 struct net_device *dev,
17970 const u8 *peer, u8 action_code,
17971 u8 dialog_token, u16 status_code,
17972 u32 peer_capability, bool initiator,
17973 const u8 *buf, size_t len)
17974#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17975static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17976 struct net_device *dev,
17977 const u8 *peer, u8 action_code,
17978 u8 dialog_token, u16 status_code,
17979 u32 peer_capability, const u8 *buf,
17980 size_t len)
17981#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17982static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17983 struct net_device *dev,
17984 u8 *peer, u8 action_code,
17985 u8 dialog_token,
17986 u16 status_code, u32 peer_capability,
17987 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017988#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017989static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17990 struct net_device *dev,
17991 u8 *peer, u8 action_code,
17992 u8 dialog_token,
17993 u16 status_code, const u8 *buf,
17994 size_t len)
17995#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017996#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017997{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017998 hdd_adapter_t *pAdapter;
17999 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018000 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070018001 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080018002 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070018003 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018004 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053018005 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018006#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018007 u32 peer_capability = 0;
18008#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018009 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018010 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018011
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018012 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18013 if (NULL == pAdapter)
18014 {
18015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18016 "%s: Adapter is NULL",__func__);
18017 return -EINVAL;
18018 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018019 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18020 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
18021 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018022
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018023 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018024 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018025 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018026 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018027 "Invalid arguments");
18028 return -EINVAL;
18029 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018030
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018031 if (pHddCtx->isLogpInProgress)
18032 {
18033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18034 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053018035 wlan_hdd_tdls_set_link_status(pAdapter,
18036 peer,
18037 eTDLS_LINK_IDLE,
18038 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018039 return -EBUSY;
18040 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018041
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018042 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
18043 {
18044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18045 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
18046 return -EAGAIN;
18047 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018048
Hoonki Lee27511902013-03-14 18:19:06 -070018049 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018050 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018052 "%s: TDLS mode is disabled OR not enabled in FW."
18053 MAC_ADDRESS_STR " action %d declined.",
18054 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018055 return -ENOTSUPP;
18056 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018057
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018058 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18059
18060 if( NULL == pHddStaCtx )
18061 {
18062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18063 "%s: HDD station context NULL ",__func__);
18064 return -EINVAL;
18065 }
18066
18067 /* STA should be connected and authenticated
18068 * before sending any TDLS frames
18069 */
18070 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18071 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
18072 {
18073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18074 "STA is not connected or unauthenticated. "
18075 "connState %u, uIsAuthenticated %u",
18076 pHddStaCtx->conn_info.connState,
18077 pHddStaCtx->conn_info.uIsAuthenticated);
18078 return -EAGAIN;
18079 }
18080
Hoonki Lee27511902013-03-14 18:19:06 -070018081 /* other than teardown frame, other mgmt frames are not sent if disabled */
18082 if (SIR_MAC_TDLS_TEARDOWN != action_code)
18083 {
18084 /* if tdls_mode is disabled to respond to peer's request */
18085 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
18086 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018087 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018088 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018089 " TDLS mode is disabled. action %d declined.",
18090 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070018091
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018092 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070018093 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053018094
18095 if (vos_max_concurrent_connections_reached())
18096 {
18097 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
18098 return -EINVAL;
18099 }
Hoonki Lee27511902013-03-14 18:19:06 -070018100 }
18101
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018102 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
18103 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053018104 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018105 {
18106 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018107 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018108 " TDLS setup is ongoing. action %d declined.",
18109 __func__, MAC_ADDR_ARRAY(peer), action_code);
18110 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018111 }
18112 }
18113
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018114 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
18115 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080018116 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018117 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18118 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018119 {
18120 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
18121 we return error code at 'add_station()'. Hence we have this
18122 check again in addtion to add_station().
18123 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018124 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018125 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18127 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018128 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
18129 __func__, MAC_ADDR_ARRAY(peer), action_code,
18130 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053018131 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080018132 }
18133 else
18134 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018135 /* maximum reached. tweak to send error code to peer and return
18136 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018137 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18139 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018140 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
18141 __func__, MAC_ADDR_ARRAY(peer), status_code,
18142 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070018143 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018144 /* fall through to send setup resp with failure status
18145 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018146 }
18147 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018148 else
18149 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018150 mutex_lock(&pHddCtx->tdls_lock);
18151 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018152 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018153 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018154 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018156 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
18157 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018158 return -EPERM;
18159 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018160 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018161 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018162 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018163
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018165 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018166 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
18167 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018168
Hoonki Leea34dd892013-02-05 22:56:02 -080018169 /*Except teardown responder will not be used so just make 0*/
18170 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018171 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080018172 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018173
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018174 mutex_lock(&pHddCtx->tdls_lock);
18175 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018176
18177 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
18178 responder = pTdlsPeer->is_responder;
18179 else
Hoonki Leea34dd892013-02-05 22:56:02 -080018180 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018181 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018182 "%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 -070018183 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
18184 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018185 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018186 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080018187 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018188 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018189 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018190
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053018191 /* Discard TDLS setup if peer is removed by user app */
18192 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
18193 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18194 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
18195 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
18196
18197 mutex_lock(&pHddCtx->tdls_lock);
18198 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18199 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
18200 mutex_unlock(&pHddCtx->tdls_lock);
18201 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
18202 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
18203 MAC_ADDR_ARRAY(peer), action_code);
18204 return -EINVAL;
18205 }
18206 mutex_unlock(&pHddCtx->tdls_lock);
18207 }
18208
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018209 /* For explicit trigger of DIS_REQ come out of BMPS for
18210 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070018211 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053018212 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018213 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
18214 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070018215 {
18216 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
18217 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018219 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018220 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
18221 if (status != VOS_STATUS_SUCCESS) {
18222 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
18223 }
Hoonki Lee14621352013-04-16 17:51:19 -070018224 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018225 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018226 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018227 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
18228 }
18229 }
Hoonki Lee14621352013-04-16 17:51:19 -070018230 }
18231
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018232 /* make sure doesn't call send_mgmt() while it is pending */
18233 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
18234 {
18235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018236 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018237 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018238 ret = -EBUSY;
18239 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018240 }
18241
18242 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018243 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
18244
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018245 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
18246 pAdapter->sessionId, peer, action_code, dialog_token,
18247 status_code, peer_capability, (tANI_U8 *)buf, len,
18248 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018249
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018250 if (VOS_STATUS_SUCCESS != status)
18251 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018252 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18253 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018254 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018255 ret = -EINVAL;
18256 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018257 }
18258
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018259 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18260 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
18261 WAIT_TIME_TDLS_MGMT);
18262
Hoonki Leed37cbb32013-04-20 00:31:14 -070018263 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
18264 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
18265
18266 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018267 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070018268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070018269 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070018270 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018271 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080018272
18273 if (pHddCtx->isLogpInProgress)
18274 {
18275 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18276 "%s: LOGP in Progress. Ignore!!!", __func__);
18277 return -EAGAIN;
18278 }
Abhishek Singh837adf22015-10-01 17:37:37 +053018279 if (rc <= 0)
18280 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
18281 WLAN_LOG_INDICATOR_HOST_DRIVER,
18282 WLAN_LOG_REASON_HDD_TIME_OUT,
18283 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080018284
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018285 ret = -EINVAL;
18286 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018287 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018288 else
18289 {
18290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18291 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
18292 __func__, rc, pAdapter->mgmtTxCompletionStatus);
18293 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018294
Gopichand Nakkala05922802013-03-14 12:23:19 -070018295 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070018296 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018297 ret = max_sta_failed;
18298 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070018299 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018300
Hoonki Leea34dd892013-02-05 22:56:02 -080018301 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
18302 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018303 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018304 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18305 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018306 }
18307 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
18308 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018309 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018310 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18311 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018312 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018313
18314 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018315
18316tx_failed:
18317 /* add_station will be called before sending TDLS_SETUP_REQ and
18318 * TDLS_SETUP_RSP and as part of add_station driver will enable
18319 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
18320 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
18321 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
18322 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
18323 */
18324
18325 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18326 (SIR_MAC_TDLS_SETUP_RSP == action_code))
18327 wlan_hdd_tdls_check_bmps(pAdapter);
18328 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018329}
18330
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018331#if TDLS_MGMT_VERSION2
18332static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18333 u8 *peer, u8 action_code, u8 dialog_token,
18334 u16 status_code, u32 peer_capability,
18335 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018336#else /* TDLS_MGMT_VERSION2 */
18337#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18338static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18339 struct net_device *dev,
18340 const u8 *peer, u8 action_code,
18341 u8 dialog_token, u16 status_code,
18342 u32 peer_capability, bool initiator,
18343 const u8 *buf, size_t len)
18344#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18345static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18346 struct net_device *dev,
18347 const u8 *peer, u8 action_code,
18348 u8 dialog_token, u16 status_code,
18349 u32 peer_capability, const u8 *buf,
18350 size_t len)
18351#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18352static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18353 struct net_device *dev,
18354 u8 *peer, u8 action_code,
18355 u8 dialog_token,
18356 u16 status_code, u32 peer_capability,
18357 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018358#else
18359static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18360 u8 *peer, u8 action_code, u8 dialog_token,
18361 u16 status_code, const u8 *buf, size_t len)
18362#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018363#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018364{
18365 int ret;
18366
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018367 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018368#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018369 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18370 dialog_token, status_code,
18371 peer_capability, buf, len);
18372#else /* TDLS_MGMT_VERSION2 */
18373#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
18374 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18375 dialog_token, status_code,
18376 peer_capability, initiator,
18377 buf, len);
18378#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
18379 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18380 dialog_token, status_code,
18381 peer_capability, buf, len);
18382#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
18383 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18384 dialog_token, status_code,
18385 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018386#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018387 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18388 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018389#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018390#endif
18391 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018392
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018393 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018394}
Atul Mittal115287b2014-07-08 13:26:33 +053018395
18396int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018397#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18398 const u8 *peer,
18399#else
Atul Mittal115287b2014-07-08 13:26:33 +053018400 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018401#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018402 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053018403 cfg80211_exttdls_callback callback)
18404{
18405
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018406 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053018407 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018408 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053018409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18410 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
18411 __func__, MAC_ADDR_ARRAY(peer));
18412
18413 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18414 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18415
18416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018417 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18418 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18419 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018420 return -ENOTSUPP;
18421 }
18422
18423 /* To cater the requirement of establishing the TDLS link
18424 * irrespective of the data traffic , get an entry of TDLS peer.
18425 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053018426 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018427 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
18428 if (pTdlsPeer == NULL) {
18429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18430 "%s: peer " MAC_ADDRESS_STR " not existing",
18431 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053018432 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018433 return -EINVAL;
18434 }
18435
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053018436 /* check FW TDLS Off Channel capability */
18437 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053018438 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053018439 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018440 {
18441 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
18442 pTdlsPeer->peerParams.global_operating_class =
18443 tdls_peer_params->global_operating_class;
18444 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
18445 pTdlsPeer->peerParams.min_bandwidth_kbps =
18446 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018447 /* check configured channel is valid, non dfs and
18448 * not current operating channel */
18449 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
18450 tdls_peer_params->channel)) &&
18451 (pHddStaCtx) &&
18452 (tdls_peer_params->channel !=
18453 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018454 {
18455 pTdlsPeer->isOffChannelConfigured = TRUE;
18456 }
18457 else
18458 {
18459 pTdlsPeer->isOffChannelConfigured = FALSE;
18460 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18461 "%s: Configured Tdls Off Channel is not valid", __func__);
18462
18463 }
18464 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018465 "%s: tdls_off_channel %d isOffChannelConfigured %d "
18466 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018467 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018468 pTdlsPeer->isOffChannelConfigured,
18469 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018470 }
18471 else
18472 {
18473 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053018474 "%s: TDLS off channel FW capability %d, "
18475 "host capab %d or Invalid TDLS Peer Params", __func__,
18476 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
18477 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018478 }
18479
Atul Mittal115287b2014-07-08 13:26:33 +053018480 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
18481
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018482 mutex_unlock(&pHddCtx->tdls_lock);
18483
Atul Mittal115287b2014-07-08 13:26:33 +053018484 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18485 " %s TDLS Add Force Peer Failed",
18486 __func__);
18487 return -EINVAL;
18488 }
18489 /*EXT TDLS*/
18490
18491 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018492 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18494 " %s TDLS set callback Failed",
18495 __func__);
18496 return -EINVAL;
18497 }
18498
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018499 mutex_unlock(&pHddCtx->tdls_lock);
18500
Atul Mittal115287b2014-07-08 13:26:33 +053018501 return(0);
18502
18503}
18504
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018505int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
18506#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18507 const u8 *peer
18508#else
18509 u8 *peer
18510#endif
18511)
Atul Mittal115287b2014-07-08 13:26:33 +053018512{
18513
18514 hddTdlsPeer_t *pTdlsPeer;
18515 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053018516
Atul Mittal115287b2014-07-08 13:26:33 +053018517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18518 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
18519 __func__, MAC_ADDR_ARRAY(peer));
18520
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018521 if (0 != wlan_hdd_validate_context(pHddCtx)) {
18522 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
18523 return -EINVAL;
18524 }
18525
Atul Mittal115287b2014-07-08 13:26:33 +053018526 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18527 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18528
18529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018530 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18531 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18532 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018533 return -ENOTSUPP;
18534 }
18535
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018536 mutex_lock(&pHddCtx->tdls_lock);
18537 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053018538
18539 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018540 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018541 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018542 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053018543 __func__, MAC_ADDR_ARRAY(peer));
18544 return -EINVAL;
18545 }
18546 else {
18547 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
18548 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053018549 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
18550 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018551 /* if channel switch is configured, reset
18552 the channel for this peer */
18553 if (TRUE == pTdlsPeer->isOffChannelConfigured)
18554 {
18555 pTdlsPeer->peerParams.channel = 0;
18556 pTdlsPeer->isOffChannelConfigured = FALSE;
18557 }
Atul Mittal115287b2014-07-08 13:26:33 +053018558 }
18559
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018560 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018561 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018562 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053018563 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018564 }
Atul Mittal115287b2014-07-08 13:26:33 +053018565
18566 /*EXT TDLS*/
18567
18568 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018569 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18571 " %s TDLS set callback Failed",
18572 __func__);
18573 return -EINVAL;
18574 }
Atul Mittal115287b2014-07-08 13:26:33 +053018575
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018576 mutex_unlock(&pHddCtx->tdls_lock);
18577
18578 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053018579}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018580static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018581#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18582 const u8 *peer,
18583#else
18584 u8 *peer,
18585#endif
18586 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018587{
18588 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18589 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018590 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018591 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018592
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018593 ENTER();
18594
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018595 if (!pAdapter) {
18596 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
18597 return -EINVAL;
18598 }
18599
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018600 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18601 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
18602 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018603 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018604 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070018606 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018607 return -EINVAL;
18608 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018609
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018610 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018611 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018612 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018613 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018614 }
18615
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018616
18617 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018618 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018619 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018621 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
18622 "Cannot process TDLS commands",
18623 pHddCtx->cfg_ini->fEnableTDLSSupport,
18624 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018625 return -ENOTSUPP;
18626 }
18627
18628 switch (oper) {
18629 case NL80211_TDLS_ENABLE_LINK:
18630 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018631 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018632 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053018633 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
18634 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053018635 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018636 tANI_U16 numCurrTdlsPeers = 0;
18637 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018638 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018639 tSirMacAddr peerMac;
18640 int channel;
18641 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018642
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18644 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
18645 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018646
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018647 mutex_lock(&pHddCtx->tdls_lock);
18648 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018649 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053018650 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018651 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018652 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18653 " (oper %d) not exsting. ignored",
18654 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18655 return -EINVAL;
18656 }
18657
18658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18659 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18660 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18661 "NL80211_TDLS_ENABLE_LINK");
18662
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018663 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
18664 {
18665 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
18666 MAC_ADDRESS_STR " failed",
18667 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018668 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018669 return -EINVAL;
18670 }
18671
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018672 /* before starting tdls connection, set tdls
18673 * off channel established status to default value */
18674 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018675
18676 mutex_unlock(&pHddCtx->tdls_lock);
18677
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053018678 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018679 /* TDLS Off Channel, Disable tdls channel switch,
18680 when there are more than one tdls link */
18681 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053018682 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018683 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018684 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018685 /* get connected peer and send disable tdls off chan */
18686 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018687 if ((connPeer) &&
18688 (connPeer->isOffChannelSupported == TRUE) &&
18689 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018690 {
18691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18692 "%s: More then one peer connected, Disable "
18693 "TDLS channel switch", __func__);
18694
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018695 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018696 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
18697 channel = connPeer->peerParams.channel;
18698
18699 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018700
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018701 ret = sme_SendTdlsChanSwitchReq(
18702 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018703 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018704 peerMac,
18705 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018706 TDLS_OFF_CHANNEL_BW_OFFSET,
18707 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018708 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018709 hddLog(VOS_TRACE_LEVEL_ERROR,
18710 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018711 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018712 }
18713 else
18714 {
18715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18716 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018717 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018718 "isOffChannelConfigured %d",
18719 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018720 (connPeer ? (connPeer->isOffChannelSupported)
18721 : -1),
18722 (connPeer ? (connPeer->isOffChannelConfigured)
18723 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018724 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018725 }
18726 }
18727
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018728 mutex_lock(&pHddCtx->tdls_lock);
18729 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18730 if ( NULL == pTdlsPeer ) {
18731 mutex_unlock(&pHddCtx->tdls_lock);
18732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18733 "%s: " MAC_ADDRESS_STR
18734 " (oper %d) peer got freed in other context. ignored",
18735 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18736 return -EINVAL;
18737 }
18738 peer_status = pTdlsPeer->link_status;
18739 mutex_unlock(&pHddCtx->tdls_lock);
18740
18741 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018742 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018743 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053018744
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018745 if (0 != wlan_hdd_tdls_get_link_establish_params(
18746 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018747 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018748 return -EINVAL;
18749 }
18750 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018751
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018752 ret = sme_SendTdlsLinkEstablishParams(
18753 WLAN_HDD_GET_HAL_CTX(pAdapter),
18754 pAdapter->sessionId, peer,
18755 &tdlsLinkEstablishParams);
18756 if (ret != VOS_STATUS_SUCCESS) {
18757 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
18758 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018759 /* Send TDLS peer UAPSD capabilities to the firmware and
18760 * register with the TL on after the response for this operation
18761 * is received .
18762 */
18763 ret = wait_for_completion_interruptible_timeout(
18764 &pAdapter->tdls_link_establish_req_comp,
18765 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053018766
18767 mutex_lock(&pHddCtx->tdls_lock);
18768 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18769 if ( NULL == pTdlsPeer ) {
18770 mutex_unlock(&pHddCtx->tdls_lock);
18771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18772 "%s %d: " MAC_ADDRESS_STR
18773 " (oper %d) peer got freed in other context. ignored",
18774 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
18775 (int)oper);
18776 return -EINVAL;
18777 }
18778 peer_status = pTdlsPeer->link_status;
18779 mutex_unlock(&pHddCtx->tdls_lock);
18780
18781 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018782 {
18783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018784 FL("Link Establish Request Failed Status %ld"),
18785 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018786 return -EINVAL;
18787 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018788 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018789
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018790 mutex_lock(&pHddCtx->tdls_lock);
18791 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18792 if ( NULL == pTdlsPeer ) {
18793 mutex_unlock(&pHddCtx->tdls_lock);
18794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18795 "%s: " MAC_ADDRESS_STR
18796 " (oper %d) peer got freed in other context. ignored",
18797 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18798 return -EINVAL;
18799 }
18800
Atul Mittal115287b2014-07-08 13:26:33 +053018801 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18802 eTDLS_LINK_CONNECTED,
18803 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018804 staDesc.ucSTAId = pTdlsPeer->staId;
18805 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053018806
18807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18808 "%s: tdlsLinkEstablishParams of peer "
18809 MAC_ADDRESS_STR "uapsdQueues: %d"
18810 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
18811 "isResponder: %d peerstaId: %d",
18812 __func__,
18813 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
18814 tdlsLinkEstablishParams.uapsdQueues,
18815 tdlsLinkEstablishParams.qos,
18816 tdlsLinkEstablishParams.maxSp,
18817 tdlsLinkEstablishParams.isBufSta,
18818 tdlsLinkEstablishParams.isOffChannelSupported,
18819 tdlsLinkEstablishParams.isResponder,
18820 pTdlsPeer->staId);
18821
18822 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18823 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
18824 __func__,
18825 staDesc.ucSTAId,
18826 staDesc.ucQosEnabled);
18827
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018828 ret = WLANTL_UpdateTdlsSTAClient(
18829 pHddCtx->pvosContext,
18830 &staDesc);
18831 if (ret != VOS_STATUS_SUCCESS) {
18832 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
18833 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053018834
Gopichand Nakkala471708b2013-06-04 20:03:01 +053018835 /* Mark TDLS client Authenticated .*/
18836 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
18837 pTdlsPeer->staId,
18838 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018839 if (VOS_STATUS_SUCCESS == status)
18840 {
Hoonki Lee14621352013-04-16 17:51:19 -070018841 if (pTdlsPeer->is_responder == 0)
18842 {
18843 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018844 tdlsConnInfo_t *tdlsInfo;
18845
18846 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
18847
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018848 if (!vos_timer_is_initialized(
18849 &pTdlsPeer->initiatorWaitTimeoutTimer))
18850 {
18851 /* Initialize initiator wait callback */
18852 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018853 &pTdlsPeer->initiatorWaitTimeoutTimer,
18854 VOS_TIMER_TYPE_SW,
18855 wlan_hdd_tdls_initiator_wait_cb,
18856 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018857 }
Hoonki Lee14621352013-04-16 17:51:19 -070018858 wlan_hdd_tdls_timer_restart(pAdapter,
18859 &pTdlsPeer->initiatorWaitTimeoutTimer,
18860 WAIT_TIME_TDLS_INITIATOR);
18861 /* suspend initiator TX until it receives direct packet from the
18862 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018863 ret = WLANTL_SuspendDataTx(
18864 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18865 &staId, NULL);
18866 if (ret != VOS_STATUS_SUCCESS) {
18867 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
18868 }
Hoonki Lee14621352013-04-16 17:51:19 -070018869 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018870
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018871 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018872 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018873 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018874 suppChannelLen =
18875 tdlsLinkEstablishParams.supportedChannelsLen;
18876
18877 if ((suppChannelLen > 0) &&
18878 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
18879 {
18880 tANI_U8 suppPeerChannel = 0;
18881 int i = 0;
18882 for (i = 0U; i < suppChannelLen; i++)
18883 {
18884 suppPeerChannel =
18885 tdlsLinkEstablishParams.supportedChannels[i];
18886
18887 pTdlsPeer->isOffChannelSupported = FALSE;
18888 if (suppPeerChannel ==
18889 pTdlsPeer->peerParams.channel)
18890 {
18891 pTdlsPeer->isOffChannelSupported = TRUE;
18892 break;
18893 }
18894 }
18895 }
18896 else
18897 {
18898 pTdlsPeer->isOffChannelSupported = FALSE;
18899 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018900 }
18901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18902 "%s: TDLS channel switch request for channel "
18903 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018904 "%d isOffChannelSupported %d", __func__,
18905 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018906 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018907 suppChannelLen,
18908 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018909
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018910 /* TDLS Off Channel, Enable tdls channel switch,
18911 when their is only one tdls link and it supports */
18912 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18913 if ((numCurrTdlsPeers == 1) &&
18914 (TRUE == pTdlsPeer->isOffChannelSupported) &&
18915 (TRUE == pTdlsPeer->isOffChannelConfigured))
18916 {
18917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18918 "%s: Send TDLS channel switch request for channel %d",
18919 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018920
18921 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018922 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
18923 channel = pTdlsPeer->peerParams.channel;
18924
18925 mutex_unlock(&pHddCtx->tdls_lock);
18926
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018927 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
18928 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018929 peerMac,
18930 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018931 TDLS_OFF_CHANNEL_BW_OFFSET,
18932 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018933 if (ret != VOS_STATUS_SUCCESS) {
18934 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
18935 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018936 }
18937 else
18938 {
18939 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18940 "%s: TDLS channel switch request not sent"
18941 " numCurrTdlsPeers %d "
18942 "isOffChannelSupported %d "
18943 "isOffChannelConfigured %d",
18944 __func__, numCurrTdlsPeers,
18945 pTdlsPeer->isOffChannelSupported,
18946 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018947 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018948 }
18949
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018950 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018951 else
18952 mutex_unlock(&pHddCtx->tdls_lock);
18953
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018954 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018955
18956 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018957 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
18958 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018959 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018960 int ac;
18961 uint8 ucAc[4] = { WLANTL_AC_VO,
18962 WLANTL_AC_VI,
18963 WLANTL_AC_BK,
18964 WLANTL_AC_BE };
18965 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
18966 for(ac=0; ac < 4; ac++)
18967 {
18968 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18969 pTdlsPeer->staId, ucAc[ac],
18970 tlTid[ac], tlTid[ac], 0, 0,
18971 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018972 if (status != VOS_STATUS_SUCCESS) {
18973 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
18974 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018975 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018976 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018977 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018978
Bhargav Shah66896792015-10-01 18:17:37 +053018979 /* stop TCP delack timer if TDLS is enable */
18980 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18981 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053018982 hdd_wlan_tdls_enable_link_event(peer,
18983 pTdlsPeer->isOffChannelSupported,
18984 pTdlsPeer->isOffChannelConfigured,
18985 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018986 }
18987 break;
18988 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080018989 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018990 tANI_U16 numCurrTdlsPeers = 0;
18991 hddTdlsPeer_t *connPeer = NULL;
18992
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18994 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
18995 __func__, MAC_ADDR_ARRAY(peer));
18996
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018997 mutex_lock(&pHddCtx->tdls_lock);
18998 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018999
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019000
Sunil Dutt41de4e22013-11-14 18:09:02 +053019001 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019002 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019003 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19004 " (oper %d) not exsting. ignored",
19005 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19006 return -EINVAL;
19007 }
19008
19009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19010 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19011 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19012 "NL80211_TDLS_DISABLE_LINK");
19013
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019014 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080019015 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019016 long status;
19017
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019018 /* set tdls off channel status to false for this peer */
19019 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053019020 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
19021 eTDLS_LINK_TEARING,
19022 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
19023 eTDLS_LINK_UNSPECIFIED:
19024 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019025 mutex_unlock(&pHddCtx->tdls_lock);
19026
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019027 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
19028
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019029 status = sme_DeleteTdlsPeerSta(
19030 WLAN_HDD_GET_HAL_CTX(pAdapter),
19031 pAdapter->sessionId, peer );
19032 if (status != VOS_STATUS_SUCCESS) {
19033 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
19034 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019035
19036 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
19037 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019038
19039 mutex_lock(&pHddCtx->tdls_lock);
19040 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19041 if ( NULL == pTdlsPeer ) {
19042 mutex_unlock(&pHddCtx->tdls_lock);
19043 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19044 " peer was freed in other context",
19045 __func__, MAC_ADDR_ARRAY(peer));
19046 return -EINVAL;
19047 }
19048
Atul Mittal271a7652014-09-12 13:18:22 +053019049 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053019050 eTDLS_LINK_IDLE,
19051 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019052 mutex_unlock(&pHddCtx->tdls_lock);
19053
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019054 if (status <= 0)
19055 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019056 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19057 "%s: Del station failed status %ld",
19058 __func__, status);
19059 return -EPERM;
19060 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019061
19062 /* TDLS Off Channel, Enable tdls channel switch,
19063 when their is only one tdls link and it supports */
19064 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19065 if (numCurrTdlsPeers == 1)
19066 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019067 tSirMacAddr peerMac;
19068 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019069
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019070 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019071 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019072
19073 if (connPeer == NULL) {
19074 mutex_unlock(&pHddCtx->tdls_lock);
19075 hddLog(VOS_TRACE_LEVEL_ERROR,
19076 "%s connPeer is NULL", __func__);
19077 return -EINVAL;
19078 }
19079
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019080 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
19081 channel = connPeer->peerParams.channel;
19082
19083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19084 "%s: TDLS channel switch "
19085 "isOffChannelSupported %d "
19086 "isOffChannelConfigured %d "
19087 "isOffChannelEstablished %d",
19088 __func__,
19089 (connPeer ? connPeer->isOffChannelSupported : -1),
19090 (connPeer ? connPeer->isOffChannelConfigured : -1),
19091 (connPeer ? connPeer->isOffChannelEstablished : -1));
19092
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019093 if ((connPeer) &&
19094 (connPeer->isOffChannelSupported == TRUE) &&
19095 (connPeer->isOffChannelConfigured == TRUE))
19096 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019097 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019098 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019099 status = sme_SendTdlsChanSwitchReq(
19100 WLAN_HDD_GET_HAL_CTX(pAdapter),
19101 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019102 peerMac,
19103 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019104 TDLS_OFF_CHANNEL_BW_OFFSET,
19105 TDLS_CHANNEL_SWITCH_ENABLE);
19106 if (status != VOS_STATUS_SUCCESS) {
19107 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
19108 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019109 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019110 else
19111 mutex_unlock(&pHddCtx->tdls_lock);
19112 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019113 else
19114 {
19115 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19116 "%s: TDLS channel switch request not sent "
19117 "numCurrTdlsPeers %d ",
19118 __func__, numCurrTdlsPeers);
19119 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019120 }
19121 else
19122 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019123 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19125 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080019126 }
Bhargav Shah66896792015-10-01 18:17:37 +053019127 if (numCurrTdlsPeers == 0) {
19128 /* start TCP delack timer if TDLS is disable */
19129 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
19130 hdd_manage_delack_timer(pHddCtx);
19131 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019132 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019133 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019134 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019135 {
Atul Mittal115287b2014-07-08 13:26:33 +053019136 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019137
Atul Mittal115287b2014-07-08 13:26:33 +053019138 if (0 != status)
19139 {
19140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019141 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053019142 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019143 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053019144 break;
19145 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019146 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019147 {
Atul Mittal115287b2014-07-08 13:26:33 +053019148 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
19149 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019150 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053019151 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019152
Atul Mittal115287b2014-07-08 13:26:33 +053019153 if (0 != status)
19154 {
19155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019156 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053019157 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053019158 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053019159 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019160 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019161 case NL80211_TDLS_DISCOVERY_REQ:
19162 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019164 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019165 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019166 return -ENOTSUPP;
19167 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19169 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019170 return -ENOTSUPP;
19171 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019172
19173 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019174 return 0;
19175}
Chilam NG571c65a2013-01-19 12:27:36 +053019176
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019177static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019178#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19179 const u8 *peer,
19180#else
19181 u8 *peer,
19182#endif
19183 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019184{
19185 int ret;
19186
19187 vos_ssr_protect(__func__);
19188 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
19189 vos_ssr_unprotect(__func__);
19190
19191 return ret;
19192}
19193
Chilam NG571c65a2013-01-19 12:27:36 +053019194int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
19195 struct net_device *dev, u8 *peer)
19196{
Arif Hussaina7c8e412013-11-20 11:06:42 -080019197 hddLog(VOS_TRACE_LEVEL_INFO,
19198 "tdls send discover req: "MAC_ADDRESS_STR,
19199 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019200#if TDLS_MGMT_VERSION2
19201 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19202 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19203#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019204#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19205 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19206 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
19207#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19208 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19209 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19210#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19211 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19212 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19213#else
Chilam NG571c65a2013-01-19 12:27:36 +053019214 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19215 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019216#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019217#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053019218}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019219#endif
19220
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019221#ifdef WLAN_FEATURE_GTK_OFFLOAD
19222/*
19223 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
19224 * Callback rountine called upon receiving response for
19225 * get offload info
19226 */
19227void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
19228 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
19229{
19230
19231 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019232 tANI_U8 tempReplayCounter[8];
19233 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019234
19235 ENTER();
19236
19237 if (NULL == pAdapter)
19238 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019240 "%s: HDD adapter is Null", __func__);
19241 return ;
19242 }
19243
19244 if (NULL == pGtkOffloadGetInfoRsp)
19245 {
19246 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19247 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
19248 return ;
19249 }
19250
19251 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
19252 {
19253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19254 "%s: wlan Failed to get replay counter value",
19255 __func__);
19256 return ;
19257 }
19258
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019259 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19260 /* Update replay counter */
19261 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
19262 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19263
19264 {
19265 /* changing from little to big endian since supplicant
19266 * works on big endian format
19267 */
19268 int i;
19269 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19270
19271 for (i = 0; i < 8; i++)
19272 {
19273 tempReplayCounter[7-i] = (tANI_U8)p[i];
19274 }
19275 }
19276
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019277 /* Update replay counter to NL */
19278 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019279 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019280}
19281
19282/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019283 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019284 * This function is used to offload GTK rekeying job to the firmware.
19285 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019286int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019287 struct cfg80211_gtk_rekey_data *data)
19288{
19289 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19290 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19291 hdd_station_ctx_t *pHddStaCtx;
19292 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019293 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019294 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019295 eHalStatus status = eHAL_STATUS_FAILURE;
19296
19297 ENTER();
19298
19299 if (NULL == pAdapter)
19300 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019302 "%s: HDD adapter is Null", __func__);
19303 return -ENODEV;
19304 }
19305
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019306 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19307 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
19308 pAdapter->sessionId, pAdapter->device_mode));
19309
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019310 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019311 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019312 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019313 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019314 }
19315
19316 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19317 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19318 if (NULL == hHal)
19319 {
19320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19321 "%s: HAL context is Null!!!", __func__);
19322 return -EAGAIN;
19323 }
19324
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019325 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
19326 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
19327 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
19328 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019329 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019330 {
19331 /* changing from big to little endian since driver
19332 * works on little endian format
19333 */
19334 tANI_U8 *p =
19335 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
19336 int i;
19337
19338 for (i = 0; i < 8; i++)
19339 {
19340 p[7-i] = data->replay_ctr[i];
19341 }
19342 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019343
19344 if (TRUE == pHddCtx->hdd_wlan_suspended)
19345 {
19346 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019347 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
19348 sizeof (tSirGtkOffloadParams));
19349 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019350 pAdapter->sessionId);
19351
19352 if (eHAL_STATUS_SUCCESS != status)
19353 {
19354 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19355 "%s: sme_SetGTKOffload failed, returned %d",
19356 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019357
19358 /* Need to clear any trace of key value in the memory.
19359 * Thus zero out the memory even though it is local
19360 * variable.
19361 */
19362 vos_mem_zero(&hddGtkOffloadReqParams,
19363 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019364 return status;
19365 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019366 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19367 "%s: sme_SetGTKOffload successfull", __func__);
19368 }
19369 else
19370 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19372 "%s: wlan not suspended GTKOffload request is stored",
19373 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019374 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019375
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019376 /* Need to clear any trace of key value in the memory.
19377 * Thus zero out the memory even though it is local
19378 * variable.
19379 */
19380 vos_mem_zero(&hddGtkOffloadReqParams,
19381 sizeof(hddGtkOffloadReqParams));
19382
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019383 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019384 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019385}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019386
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019387int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
19388 struct cfg80211_gtk_rekey_data *data)
19389{
19390 int ret;
19391
19392 vos_ssr_protect(__func__);
19393 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
19394 vos_ssr_unprotect(__func__);
19395
19396 return ret;
19397}
19398#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019399/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019400 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019401 * This function is used to set access control policy
19402 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019403static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19404 struct net_device *dev,
19405 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019406{
19407 int i;
19408 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19409 hdd_hostapd_state_t *pHostapdState;
19410 tsap_Config_t *pConfig;
19411 v_CONTEXT_t pVosContext = NULL;
19412 hdd_context_t *pHddCtx;
19413 int status;
19414
19415 ENTER();
19416
19417 if (NULL == pAdapter)
19418 {
19419 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19420 "%s: HDD adapter is Null", __func__);
19421 return -ENODEV;
19422 }
19423
19424 if (NULL == params)
19425 {
19426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19427 "%s: params is Null", __func__);
19428 return -EINVAL;
19429 }
19430
19431 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19432 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019433 if (0 != status)
19434 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019435 return status;
19436 }
19437
19438 pVosContext = pHddCtx->pvosContext;
19439 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
19440
19441 if (NULL == pHostapdState)
19442 {
19443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19444 "%s: pHostapdState is Null", __func__);
19445 return -EINVAL;
19446 }
19447
19448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
19449 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019450 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19451 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
19452 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019453
19454 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
19455 {
19456 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
19457
19458 /* default value */
19459 pConfig->num_accept_mac = 0;
19460 pConfig->num_deny_mac = 0;
19461
19462 /**
19463 * access control policy
19464 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
19465 * listed in hostapd.deny file.
19466 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
19467 * listed in hostapd.accept file.
19468 */
19469 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
19470 {
19471 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
19472 }
19473 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
19474 {
19475 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
19476 }
19477 else
19478 {
19479 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19480 "%s:Acl Policy : %d is not supported",
19481 __func__, params->acl_policy);
19482 return -ENOTSUPP;
19483 }
19484
19485 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
19486 {
19487 pConfig->num_accept_mac = params->n_acl_entries;
19488 for (i = 0; i < params->n_acl_entries; i++)
19489 {
19490 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19491 "** Add ACL MAC entry %i in WhiletList :"
19492 MAC_ADDRESS_STR, i,
19493 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
19494
19495 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
19496 sizeof(qcmacaddr));
19497 }
19498 }
19499 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
19500 {
19501 pConfig->num_deny_mac = params->n_acl_entries;
19502 for (i = 0; i < params->n_acl_entries; i++)
19503 {
19504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19505 "** Add ACL MAC entry %i in BlackList :"
19506 MAC_ADDRESS_STR, i,
19507 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
19508
19509 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
19510 sizeof(qcmacaddr));
19511 }
19512 }
19513
19514 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
19515 {
19516 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19517 "%s: SAP Set Mac Acl fail", __func__);
19518 return -EINVAL;
19519 }
19520 }
19521 else
19522 {
19523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053019524 "%s: Invalid device_mode = %s (%d)",
19525 __func__, hdd_device_modetoString(pAdapter->device_mode),
19526 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019527 return -EINVAL;
19528 }
19529
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019530 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019531 return 0;
19532}
19533
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019534static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19535 struct net_device *dev,
19536 const struct cfg80211_acl_data *params)
19537{
19538 int ret;
19539 vos_ssr_protect(__func__);
19540 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
19541 vos_ssr_unprotect(__func__);
19542
19543 return ret;
19544}
19545
Leo Chang9056f462013-08-01 19:21:11 -070019546#ifdef WLAN_NL80211_TESTMODE
19547#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070019548void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070019549(
19550 void *pAdapter,
19551 void *indCont
19552)
19553{
Leo Changd9df8aa2013-09-26 13:32:26 -070019554 tSirLPHBInd *lphbInd;
19555 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053019556 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070019557
19558 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019559 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070019560
c_hpothu73f35e62014-04-18 13:40:08 +053019561 if (pAdapter == NULL)
19562 {
19563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19564 "%s: pAdapter is NULL\n",__func__);
19565 return;
19566 }
19567
Leo Chang9056f462013-08-01 19:21:11 -070019568 if (NULL == indCont)
19569 {
19570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019571 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070019572 return;
19573 }
19574
c_hpothu73f35e62014-04-18 13:40:08 +053019575 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070019576 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070019577 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053019578 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070019579 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070019580 GFP_ATOMIC);
19581 if (!skb)
19582 {
19583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19584 "LPHB timeout, NL buffer alloc fail");
19585 return;
19586 }
19587
Leo Changac3ba772013-10-07 09:47:04 -070019588 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070019589 {
19590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19591 "WLAN_HDD_TM_ATTR_CMD put fail");
19592 goto nla_put_failure;
19593 }
Leo Changac3ba772013-10-07 09:47:04 -070019594 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070019595 {
19596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19597 "WLAN_HDD_TM_ATTR_TYPE put fail");
19598 goto nla_put_failure;
19599 }
Leo Changac3ba772013-10-07 09:47:04 -070019600 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070019601 sizeof(tSirLPHBInd), lphbInd))
19602 {
19603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19604 "WLAN_HDD_TM_ATTR_DATA put fail");
19605 goto nla_put_failure;
19606 }
Leo Chang9056f462013-08-01 19:21:11 -070019607 cfg80211_testmode_event(skb, GFP_ATOMIC);
19608 return;
19609
19610nla_put_failure:
19611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19612 "NLA Put fail");
19613 kfree_skb(skb);
19614
19615 return;
19616}
19617#endif /* FEATURE_WLAN_LPHB */
19618
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019619static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070019620{
19621 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
19622 int err = 0;
19623#ifdef FEATURE_WLAN_LPHB
19624 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070019625 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019626
19627 ENTER();
19628
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019629 err = wlan_hdd_validate_context(pHddCtx);
19630 if (0 != err)
19631 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019632 return err;
19633 }
Leo Chang9056f462013-08-01 19:21:11 -070019634#endif /* FEATURE_WLAN_LPHB */
19635
19636 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
19637 if (err)
19638 {
19639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19640 "%s Testmode INV ATTR", __func__);
19641 return err;
19642 }
19643
19644 if (!tb[WLAN_HDD_TM_ATTR_CMD])
19645 {
19646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19647 "%s Testmode INV CMD", __func__);
19648 return -EINVAL;
19649 }
19650
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019651 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19652 TRACE_CODE_HDD_CFG80211_TESTMODE,
19653 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070019654 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
19655 {
19656#ifdef FEATURE_WLAN_LPHB
19657 /* Low Power Heartbeat configuration request */
19658 case WLAN_HDD_TM_CMD_WLAN_HB:
19659 {
19660 int buf_len;
19661 void *buf;
19662 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080019663 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070019664
19665 if (!tb[WLAN_HDD_TM_ATTR_DATA])
19666 {
19667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19668 "%s Testmode INV DATA", __func__);
19669 return -EINVAL;
19670 }
19671
19672 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
19673 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080019674
19675 hb_params_temp =(tSirLPHBReq *)buf;
19676 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
19677 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
19678 return -EINVAL;
19679
Leo Chang9056f462013-08-01 19:21:11 -070019680 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
19681 if (NULL == hb_params)
19682 {
19683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19684 "%s Request Buffer Alloc Fail", __func__);
19685 return -EINVAL;
19686 }
19687
19688 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070019689 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
19690 hb_params,
19691 wlan_hdd_cfg80211_lphb_ind_handler);
19692 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070019693 {
Leo Changd9df8aa2013-09-26 13:32:26 -070019694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19695 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070019696 vos_mem_free(hb_params);
19697 }
Leo Chang9056f462013-08-01 19:21:11 -070019698 return 0;
19699 }
19700#endif /* FEATURE_WLAN_LPHB */
19701 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19703 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070019704 return -EOPNOTSUPP;
19705 }
19706
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019707 EXIT();
19708 return err;
Leo Chang9056f462013-08-01 19:21:11 -070019709}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019710
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053019711static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
19712#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
19713 struct wireless_dev *wdev,
19714#endif
19715 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019716{
19717 int ret;
19718
19719 vos_ssr_protect(__func__);
19720 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
19721 vos_ssr_unprotect(__func__);
19722
19723 return ret;
19724}
Leo Chang9056f462013-08-01 19:21:11 -070019725#endif /* CONFIG_NL80211_TESTMODE */
19726
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019727extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019728static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019729 struct net_device *dev,
19730 int idx, struct survey_info *survey)
19731{
19732 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19733 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053019734 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019735 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053019736 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019737 v_S7_t snr,rssi;
19738 int status, i, j, filled = 0;
19739
19740 ENTER();
19741
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019742 if (NULL == pAdapter)
19743 {
19744 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19745 "%s: HDD adapter is Null", __func__);
19746 return -ENODEV;
19747 }
19748
19749 if (NULL == wiphy)
19750 {
19751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19752 "%s: wiphy is Null", __func__);
19753 return -ENODEV;
19754 }
19755
19756 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19757 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019758 if (0 != status)
19759 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019760 return status;
19761 }
19762
Mihir Sheted9072e02013-08-21 17:02:29 +053019763 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19764
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019765 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053019766 0 != pAdapter->survey_idx ||
19767 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019768 {
19769 /* The survey dump ops when implemented completely is expected to
19770 * return a survey of all channels and the ops is called by the
19771 * kernel with incremental values of the argument 'idx' till it
19772 * returns -ENONET. But we can only support the survey for the
19773 * operating channel for now. survey_idx is used to track
19774 * that the ops is called only once and then return -ENONET for
19775 * the next iteration
19776 */
19777 pAdapter->survey_idx = 0;
19778 return -ENONET;
19779 }
19780
Mukul Sharma9d5233b2015-06-11 20:28:20 +053019781 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
19782 {
19783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19784 "%s: Roaming in progress, hence return ", __func__);
19785 return -ENONET;
19786 }
19787
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019788 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19789
19790 wlan_hdd_get_snr(pAdapter, &snr);
19791 wlan_hdd_get_rssi(pAdapter, &rssi);
19792
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019793 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19794 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
19795 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019796 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
19797 hdd_wlan_get_freq(channel, &freq);
19798
19799
19800 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
19801 {
19802 if (NULL == wiphy->bands[i])
19803 {
19804 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
19805 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
19806 continue;
19807 }
19808
19809 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
19810 {
19811 struct ieee80211_supported_band *band = wiphy->bands[i];
19812
19813 if (band->channels[j].center_freq == (v_U16_t)freq)
19814 {
19815 survey->channel = &band->channels[j];
19816 /* The Rx BDs contain SNR values in dB for the received frames
19817 * while the supplicant expects noise. So we calculate and
19818 * return the value of noise (dBm)
19819 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
19820 */
19821 survey->noise = rssi - snr;
19822 survey->filled = SURVEY_INFO_NOISE_DBM;
19823 filled = 1;
19824 }
19825 }
19826 }
19827
19828 if (filled)
19829 pAdapter->survey_idx = 1;
19830 else
19831 {
19832 pAdapter->survey_idx = 0;
19833 return -ENONET;
19834 }
19835
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019836 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019837 return 0;
19838}
19839
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019840static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
19841 struct net_device *dev,
19842 int idx, struct survey_info *survey)
19843{
19844 int ret;
19845
19846 vos_ssr_protect(__func__);
19847 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
19848 vos_ssr_unprotect(__func__);
19849
19850 return ret;
19851}
19852
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019853/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019854 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019855 * this is called when cfg80211 driver resume
19856 * driver updates latest sched_scan scan result(if any) to cfg80211 database
19857 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019858int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019859{
19860 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19861 hdd_adapter_t *pAdapter;
19862 hdd_adapter_list_node_t *pAdapterNode, *pNext;
19863 VOS_STATUS status = VOS_STATUS_SUCCESS;
19864
19865 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019866
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019867 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019868 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019869 return 0;
19870 }
19871
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019872 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
19873 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019874
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053019875 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019876 {
19877 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19878 "%s: Resume SoftAP", __func__);
19879 hdd_set_wlan_suspend_mode(false);
19880 }
19881
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019882 spin_lock(&pHddCtx->schedScan_lock);
19883 pHddCtx->isWiphySuspended = FALSE;
19884 if (TRUE != pHddCtx->isSchedScanUpdatePending)
19885 {
19886 spin_unlock(&pHddCtx->schedScan_lock);
19887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19888 "%s: Return resume is not due to PNO indication", __func__);
19889 return 0;
19890 }
19891 // Reset flag to avoid updatating cfg80211 data old results again
19892 pHddCtx->isSchedScanUpdatePending = FALSE;
19893 spin_unlock(&pHddCtx->schedScan_lock);
19894
19895 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
19896
19897 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
19898 {
19899 pAdapter = pAdapterNode->pAdapter;
19900 if ( (NULL != pAdapter) &&
19901 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
19902 {
19903 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019904 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019905 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19906 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019907 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019908 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019909 {
19910 /* Acquire wakelock to handle the case where APP's tries to
19911 * suspend immediately after updating the scan results. Whis
19912 * results in app's is in suspended state and not able to
19913 * process the connect request to AP
19914 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053019915 hdd_prevent_suspend_timeout(2000,
19916 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019917 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019918 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019919
19920 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19921 "%s : cfg80211 scan result database updated", __func__);
19922
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019923 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019924 return 0;
19925
19926 }
19927 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19928 pAdapterNode = pNext;
19929 }
19930
19931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19932 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019933 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019934 return 0;
19935}
19936
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019937int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
19938{
19939 int ret;
19940
19941 vos_ssr_protect(__func__);
19942 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
19943 vos_ssr_unprotect(__func__);
19944
19945 return ret;
19946}
19947
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019948/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019949 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019950 * this is called when cfg80211 driver suspends
19951 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019952int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019953 struct cfg80211_wowlan *wow)
19954{
19955 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019956 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019957
19958 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019959
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019960 ret = wlan_hdd_validate_context(pHddCtx);
19961 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019962 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019963 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019964 }
19965
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053019966 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19968 "%s: Suspend SoftAP", __func__);
19969 hdd_set_wlan_suspend_mode(true);
19970 }
19971
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019972
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019973 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19974 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
19975 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019976 pHddCtx->isWiphySuspended = TRUE;
19977
19978 EXIT();
19979
19980 return 0;
19981}
19982
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019983int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
19984 struct cfg80211_wowlan *wow)
19985{
19986 int ret;
19987
19988 vos_ssr_protect(__func__);
19989 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
19990 vos_ssr_unprotect(__func__);
19991
19992 return ret;
19993}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019994
19995#ifdef FEATURE_OEM_DATA_SUPPORT
19996static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019997 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019998{
19999 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
20000
20001 ENTER();
20002
20003 if (wlan_hdd_validate_context(pHddCtx)) {
20004 return;
20005 }
20006 if (!pMsg)
20007 {
20008 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
20009 return;
20010 }
20011
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020012 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020013
20014 EXIT();
20015 return;
20016
20017}
20018
20019void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020020 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020021{
20022 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
20023
20024 ENTER();
20025
20026 if (wlan_hdd_validate_context(pHddCtx)) {
20027 return;
20028 }
20029
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020030 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020031
20032 switch(evType) {
20033 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020034 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020035 break;
20036 default:
20037 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
20038 break;
20039 }
20040 EXIT();
20041}
20042#endif
20043
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020044#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20045 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020046/**
20047 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
20048 * @wiphy: Pointer to wiphy
20049 * @wdev: Pointer to wireless device structure
20050 *
20051 * This function is used to abort an ongoing scan
20052 *
20053 * Return: None
20054 */
20055static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20056 struct wireless_dev *wdev)
20057{
20058 struct net_device *dev = wdev->netdev;
20059 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
20060 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
20061 int ret;
20062
20063 ENTER();
20064
20065 if (NULL == adapter) {
20066 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
20067 return;
20068 }
20069
20070 ret = wlan_hdd_validate_context(hdd_ctx);
20071 if (0 != ret)
20072 return;
20073
20074 wlan_hdd_scan_abort(adapter);
20075
20076 return;
20077}
20078
20079/**
20080 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
20081 * @wiphy: Pointer to wiphy
20082 * @wdev: Pointer to wireless device structure
20083 *
20084 * Return: None
20085 */
20086void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20087 struct wireless_dev *wdev)
20088{
20089 vos_ssr_protect(__func__);
20090 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
20091 vos_ssr_unprotect(__func__);
20092
20093 return;
20094}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020095#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020096
Jeff Johnson295189b2012-06-20 16:38:30 -070020097/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020098static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070020099{
20100 .add_virtual_intf = wlan_hdd_add_virtual_intf,
20101 .del_virtual_intf = wlan_hdd_del_virtual_intf,
20102 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
20103 .change_station = wlan_hdd_change_station,
20104#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
20105 .add_beacon = wlan_hdd_cfg80211_add_beacon,
20106 .del_beacon = wlan_hdd_cfg80211_del_beacon,
20107 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020108#else
20109 .start_ap = wlan_hdd_cfg80211_start_ap,
20110 .change_beacon = wlan_hdd_cfg80211_change_beacon,
20111 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070020112#endif
20113 .change_bss = wlan_hdd_cfg80211_change_bss,
20114 .add_key = wlan_hdd_cfg80211_add_key,
20115 .get_key = wlan_hdd_cfg80211_get_key,
20116 .del_key = wlan_hdd_cfg80211_del_key,
20117 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020118#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070020119 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020120#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020121 .scan = wlan_hdd_cfg80211_scan,
20122 .connect = wlan_hdd_cfg80211_connect,
20123 .disconnect = wlan_hdd_cfg80211_disconnect,
20124 .join_ibss = wlan_hdd_cfg80211_join_ibss,
20125 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
20126 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
20127 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
20128 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070020129 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
20130 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053020131 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070020132#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
20133 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
20134 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
20135 .set_txq_params = wlan_hdd_set_txq_params,
20136#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020137 .get_station = wlan_hdd_cfg80211_get_station,
20138 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
20139 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020140 .add_station = wlan_hdd_cfg80211_add_station,
20141#ifdef FEATURE_WLAN_LFR
20142 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
20143 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
20144 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
20145#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070020146#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
20147 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
20148#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020149#ifdef FEATURE_WLAN_TDLS
20150 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
20151 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
20152#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020153#ifdef WLAN_FEATURE_GTK_OFFLOAD
20154 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
20155#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020156#ifdef FEATURE_WLAN_SCAN_PNO
20157 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
20158 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
20159#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020160 .resume = wlan_hdd_cfg80211_resume_wlan,
20161 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020162 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070020163#ifdef WLAN_NL80211_TESTMODE
20164 .testmode_cmd = wlan_hdd_cfg80211_testmode,
20165#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020166 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020167#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20168 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020169 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020170#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020171};
20172