blob: 5127abca14fe88464cf2264ecdaae45561b0be2f [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Abhishek Singhb3e376c2017-01-04 15:27:13 +05302 * Copyright (c) 2012-2017 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
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530783/*
784 * define short names for the global vendor params
785 * used by __wlan_hdd_cfg80211_get_station_cmd()
786 */
787#define STATION_INVALID \
788 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
789#define STATION_INFO \
790 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
791#define STATION_ASSOC_FAIL_REASON \
792 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
793#define STATION_MAX \
794 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
795
796static const struct nla_policy
797hdd_get_station_policy[STATION_MAX + 1] = {
798 [STATION_INFO] = {.type = NLA_FLAG},
799 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
800};
801
802/**
803 * hdd_get_station_assoc_fail() - Handle get station assoc fail
804 * @hdd_ctx: HDD context within host driver
805 * @wdev: wireless device
806 *
807 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
808 * Validate cmd attributes and send the station info to upper layers.
809 *
810 * Return: Success(0) or reason code for failure
811 */
812static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
813 hdd_adapter_t *adapter)
814{
815 struct sk_buff *skb = NULL;
816 uint32_t nl_buf_len;
817 hdd_station_ctx_t *hdd_sta_ctx;
818
819 nl_buf_len = NLMSG_HDRLEN;
820 nl_buf_len += sizeof(uint32_t);
821 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
822
823 if (!skb) {
824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
825 return -ENOMEM;
826 }
827
828 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
829
830 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
831 hdd_sta_ctx->conn_info.assoc_status_code)) {
832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
833 goto fail;
834 }
835 return cfg80211_vendor_cmd_reply(skb);
836fail:
837 if (skb)
838 kfree_skb(skb);
839 return -EINVAL;
840}
841
842/**
843 * hdd_map_auth_type() - transform auth type specific to
844 * vendor command
845 * @auth_type: csr auth type
846 *
847 * Return: Success(0) or reason code for failure
848 */
849static int hdd_convert_auth_type(uint32_t auth_type)
850{
851 uint32_t ret_val;
852
853 switch (auth_type) {
854 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
855 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
856 break;
857 case eCSR_AUTH_TYPE_SHARED_KEY:
858 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
859 break;
860 case eCSR_AUTH_TYPE_WPA:
861 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
862 break;
863 case eCSR_AUTH_TYPE_WPA_PSK:
864 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
865 break;
866 case eCSR_AUTH_TYPE_AUTOSWITCH:
867 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
868 break;
869 case eCSR_AUTH_TYPE_WPA_NONE:
870 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
871 break;
872 case eCSR_AUTH_TYPE_RSN:
873 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
874 break;
875 case eCSR_AUTH_TYPE_RSN_PSK:
876 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
877 break;
878 case eCSR_AUTH_TYPE_FT_RSN:
879 ret_val = QCA_WLAN_AUTH_TYPE_FT;
880 break;
881 case eCSR_AUTH_TYPE_FT_RSN_PSK:
882 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
883 break;
884 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
885 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
886 break;
887 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
888 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
889 break;
890#ifdef FEATURE_WLAN_ESE
891 case eCSR_AUTH_TYPE_CCKM_WPA:
892 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
893 break;
894 case eCSR_AUTH_TYPE_CCKM_RSN:
895 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
896 break;
897#endif
898 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
899 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
900 break;
901 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
902 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
903 break;
904 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
905 case eCSR_AUTH_TYPE_FAILED:
906 case eCSR_AUTH_TYPE_NONE:
907 default:
908 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
909 break;
910 }
911 return ret_val;
912}
913
914/**
915 * hdd_map_dot_11_mode() - transform dot11mode type specific to
916 * vendor command
917 * @dot11mode: dot11mode
918 *
919 * Return: Success(0) or reason code for failure
920 */
921static int hdd_convert_dot11mode(uint32_t dot11mode)
922{
923 uint32_t ret_val;
924
925 switch (dot11mode) {
926 case eCSR_CFG_DOT11_MODE_11A:
927 ret_val = QCA_WLAN_802_11_MODE_11A;
928 break;
929 case eCSR_CFG_DOT11_MODE_11B:
930 ret_val = QCA_WLAN_802_11_MODE_11B;
931 break;
932 case eCSR_CFG_DOT11_MODE_11G:
933 ret_val = QCA_WLAN_802_11_MODE_11G;
934 break;
935 case eCSR_CFG_DOT11_MODE_11N:
936 ret_val = QCA_WLAN_802_11_MODE_11N;
937 break;
938 case eCSR_CFG_DOT11_MODE_11AC:
939 ret_val = QCA_WLAN_802_11_MODE_11AC;
940 break;
941 case eCSR_CFG_DOT11_MODE_AUTO:
942 case eCSR_CFG_DOT11_MODE_ABG:
943 default:
944 ret_val = QCA_WLAN_802_11_MODE_INVALID;
945 }
946 return ret_val;
947}
948
949/**
950 * hdd_add_tx_bitrate() - add tx bitrate attribute
951 * @skb: pointer to sk buff
952 * @hdd_sta_ctx: pointer to hdd station context
953 * @idx: attribute index
954 *
955 * Return: Success(0) or reason code for failure
956 */
957static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
958 hdd_station_ctx_t *hdd_sta_ctx,
959 int idx)
960{
961 struct nlattr *nla_attr;
962 uint32_t bitrate, bitrate_compat;
963
964 nla_attr = nla_nest_start(skb, idx);
965 if (!nla_attr)
966 goto fail;
967 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
968 bitrate = cfg80211_calculate_bitrate(&hdd_sta_ctx->conn_info.txrate);
969
970 /* report 16-bit bitrate only if we can */
971 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
972 if (bitrate > 0 &&
973 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
974 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
975 goto fail;
976 }
977 if (bitrate_compat > 0 &&
978 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
979 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
980 goto fail;
981 }
982 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
983 hdd_sta_ctx->conn_info.txrate.nss)) {
984 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
985 goto fail;
986 }
987 nla_nest_end(skb, nla_attr);
988 return 0;
989fail:
990 return -EINVAL;
991}
992
993/**
994 * hdd_add_sta_info() - add station info attribute
995 * @skb: pointer to sk buff
996 * @hdd_sta_ctx: pointer to hdd station context
997 * @idx: attribute index
998 *
999 * Return: Success(0) or reason code for failure
1000 */
1001static int32_t hdd_add_sta_info(struct sk_buff *skb,
1002 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1003{
1004 struct nlattr *nla_attr;
1005
1006 nla_attr = nla_nest_start(skb, idx);
1007 if (!nla_attr)
1008 goto fail;
1009 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
1010 (hdd_sta_ctx->conn_info.signal + 100))) {
1011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1012 goto fail;
1013 }
1014 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1015 goto fail;
1016 nla_nest_end(skb, nla_attr);
1017 return 0;
1018fail:
1019 return -EINVAL;
1020}
1021
1022/**
1023 * hdd_add_survey_info() - add survey info attribute
1024 * @skb: pointer to sk buff
1025 * @hdd_sta_ctx: pointer to hdd station context
1026 * @idx: attribute index
1027 *
1028 * Return: Success(0) or reason code for failure
1029 */
1030static int32_t hdd_add_survey_info(struct sk_buff *skb,
1031 hdd_station_ctx_t *hdd_sta_ctx,
1032 int idx)
1033{
1034 struct nlattr *nla_attr;
1035
1036 nla_attr = nla_nest_start(skb, idx);
1037 if (!nla_attr)
1038 goto fail;
1039 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1040 hdd_sta_ctx->conn_info.freq) ||
1041 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
1042 (hdd_sta_ctx->conn_info.noise + 100))) {
1043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1044 goto fail;
1045 }
1046 nla_nest_end(skb, nla_attr);
1047 return 0;
1048fail:
1049 return -EINVAL;
1050}
1051
1052/**
1053 * hdd_add_link_standard_info() - add link info attribute
1054 * @skb: pointer to sk buff
1055 * @hdd_sta_ctx: pointer to hdd station context
1056 * @idx: attribute index
1057 *
1058 * Return: Success(0) or reason code for failure
1059 */
1060static int32_t
1061hdd_add_link_standard_info(struct sk_buff *skb,
1062 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1063{
1064 struct nlattr *nla_attr;
1065
1066 nla_attr = nla_nest_start(skb, idx);
1067 if (!nla_attr)
1068 goto fail;
1069 if (nla_put(skb,
1070 NL80211_ATTR_SSID,
1071 hdd_sta_ctx->conn_info.SSID.SSID.length,
1072 hdd_sta_ctx->conn_info.SSID.SSID.ssId)) {
1073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1074 goto fail;
1075 }
1076 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1077 goto fail;
1078 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1079 goto fail;
1080 nla_nest_end(skb, nla_attr);
1081 return 0;
1082fail:
1083 return -EINVAL;
1084}
1085
1086/**
1087 * hdd_add_ap_standard_info() - add ap info attribute
1088 * @skb: pointer to sk buff
1089 * @hdd_sta_ctx: pointer to hdd station context
1090 * @idx: attribute index
1091 *
1092 * Return: Success(0) or reason code for failure
1093 */
1094static int32_t
1095hdd_add_ap_standard_info(struct sk_buff *skb,
1096 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1097{
1098 struct nlattr *nla_attr;
1099
1100 nla_attr = nla_nest_start(skb, idx);
1101 if (!nla_attr)
1102 goto fail;
1103 if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
1104 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1105 sizeof(hdd_sta_ctx->conn_info.vht_caps),
1106 &hdd_sta_ctx->conn_info.vht_caps)) {
1107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1108 goto fail;
1109 }
1110 if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
1111 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1112 sizeof(hdd_sta_ctx->conn_info.ht_caps),
1113 &hdd_sta_ctx->conn_info.ht_caps)) {
1114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1115 goto fail;
1116 }
1117 nla_nest_end(skb, nla_attr);
1118 return 0;
1119fail:
1120 return -EINVAL;
1121}
1122
1123/**
1124 * hdd_get_station_info() - send BSS information to supplicant
1125 * @hdd_ctx: pointer to hdd context
1126 * @adapter: pointer to adapter
1127 *
1128 * Return: 0 if success else error status
1129 */
1130static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1131 hdd_adapter_t *adapter)
1132{
1133 struct sk_buff *skb = NULL;
1134 uint8_t *tmp_hs20 = NULL;
1135 uint32_t nl_buf_len;
1136 hdd_station_ctx_t *hdd_sta_ctx;
1137
1138 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1139
1140 nl_buf_len = NLMSG_HDRLEN;
1141 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.SSID.SSID.length) +
1142 sizeof(hdd_sta_ctx->conn_info.freq) +
1143 sizeof(hdd_sta_ctx->conn_info.noise) +
1144 sizeof(hdd_sta_ctx->conn_info.signal) +
1145 (sizeof(uint32_t) * 2) +
1146 sizeof(hdd_sta_ctx->conn_info.txrate.nss) +
1147 sizeof(hdd_sta_ctx->conn_info.roam_count) +
1148 sizeof(hdd_sta_ctx->conn_info.authType) +
1149 sizeof(hdd_sta_ctx->conn_info.dot11Mode);
1150 if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
1151 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_caps);
1152 if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
1153 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_caps);
1154 if (hdd_sta_ctx->conn_info.conn_flag.hs20_present) {
1155 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->conn_info.hs20vendor_ie);
1156 nl_buf_len += (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) -
1157 1);
1158 }
1159 if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
1160 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_operation);
1161 if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
1162 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_operation);
1163
1164
1165 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1166 if (!skb) {
1167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1168 __func__, __LINE__);
1169 return -ENOMEM;
1170 }
1171
1172 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1173 LINK_INFO_STANDARD_NL80211_ATTR)) {
1174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1175 goto fail;
1176 }
1177 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1178 AP_INFO_STANDARD_NL80211_ATTR)) {
1179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1180 goto fail;
1181 }
1182 if (nla_put_u32(skb, INFO_ROAM_COUNT,
1183 hdd_sta_ctx->conn_info.roam_count) ||
1184 nla_put_u32(skb, INFO_AKM,
1185 hdd_convert_auth_type(
1186 hdd_sta_ctx->conn_info.authType)) ||
1187 nla_put_u32(skb, WLAN802_11_MODE,
1188 hdd_convert_dot11mode(
1189 hdd_sta_ctx->conn_info.dot11Mode))) {
1190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1191 goto fail;
1192 }
1193 if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
1194 if (nla_put(skb, HT_OPERATION,
1195 (sizeof(hdd_sta_ctx->conn_info.ht_operation)),
1196 &hdd_sta_ctx->conn_info.ht_operation)) {
1197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1198 goto fail;
1199 }
1200 if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
1201 if (nla_put(skb, VHT_OPERATION,
1202 (sizeof(hdd_sta_ctx->conn_info.vht_operation)),
1203 &hdd_sta_ctx->conn_info.vht_operation)) {
1204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1205 goto fail;
1206 }
1207 if (hdd_sta_ctx->conn_info.conn_flag.hs20_present)
1208 if (nla_put(skb, AP_INFO_HS20_INDICATION,
1209 (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) - 1),
1210 tmp_hs20 + 1)) {
1211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1212 goto fail;
1213 }
1214
1215 return cfg80211_vendor_cmd_reply(skb);
1216fail:
1217 if (skb)
1218 kfree_skb(skb);
1219 return -EINVAL;
1220}
1221
1222/**
1223 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1224 * @wiphy: corestack handler
1225 * @wdev: wireless device
1226 * @data: data
1227 * @data_len: data length
1228 *
1229 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1230 * Validate cmd attributes and send the station info to upper layers.
1231 *
1232 * Return: Success(0) or reason code for failure
1233 */
1234static int32_t
1235__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1236 struct wireless_dev *wdev,
1237 const void *data,
1238 int data_len)
1239{
1240 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1241 struct net_device *dev = wdev->netdev;
1242 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1243 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1244 int32_t status;
1245
1246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1247 if (VOS_FTM_MODE == hdd_get_conparam()) {
1248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1249 status = -EPERM;
1250 goto out;
1251 }
1252
1253 status = wlan_hdd_validate_context(hdd_ctx);
1254 if (0 != status)
1255 goto out;
1256
1257
1258 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1259 data, data_len, NULL);
1260 if (status) {
1261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1262 goto out;
1263 }
1264
1265 /* Parse and fetch Command Type*/
1266 if (tb[STATION_INFO]) {
1267 status = hdd_get_station_info(hdd_ctx, adapter);
1268 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1269 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
1270 } else {
1271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1272 status = -EINVAL;
1273 goto out;
1274 }
1275 EXIT();
1276out:
1277 return status;
1278}
1279
1280/**
1281 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1282 * @wiphy: corestack handler
1283 * @wdev: wireless device
1284 * @data: data
1285 * @data_len: data length
1286 *
1287 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1288 * Validate cmd attributes and send the station info to upper layers.
1289 *
1290 * Return: Success(0) or reason code for failure
1291 */
1292static int32_t
1293hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1294 struct wireless_dev *wdev,
1295 const void *data,
1296 int data_len)
1297{
1298 int ret;
1299
1300 vos_ssr_protect(__func__);
1301 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1302 vos_ssr_unprotect(__func__);
1303
1304 return ret;
1305}
1306
1307/*
1308 * undef short names defined for get station command
1309 * used by __wlan_hdd_cfg80211_get_station_cmd()
1310 */
1311#undef STATION_INVALID
1312#undef STATION_INFO
1313#undef STATION_ASSOC_FAIL_REASON
1314#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301315
Sunil Duttc69bccb2014-05-26 21:30:20 +05301316#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1317
1318static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1319 struct sk_buff *vendor_event)
1320{
1321 if (nla_put_u8(vendor_event,
1322 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1323 stats->rate.preamble) ||
1324 nla_put_u8(vendor_event,
1325 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1326 stats->rate.nss) ||
1327 nla_put_u8(vendor_event,
1328 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1329 stats->rate.bw) ||
1330 nla_put_u8(vendor_event,
1331 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1332 stats->rate.rateMcsIdx) ||
1333 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1334 stats->rate.bitrate ) ||
1335 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1336 stats->txMpdu ) ||
1337 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1338 stats->rxMpdu ) ||
1339 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1340 stats->mpduLost ) ||
1341 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1342 stats->retries) ||
1343 nla_put_u32(vendor_event,
1344 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1345 stats->retriesShort ) ||
1346 nla_put_u32(vendor_event,
1347 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1348 stats->retriesLong))
1349 {
1350 hddLog(VOS_TRACE_LEVEL_ERROR,
1351 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1352 return FALSE;
1353 }
1354 return TRUE;
1355}
1356
1357static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1358 struct sk_buff *vendor_event)
1359{
1360 u32 i = 0;
1361 struct nlattr *rateInfo;
1362 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1363 stats->type) ||
1364 nla_put(vendor_event,
1365 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1366 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1367 nla_put_u32(vendor_event,
1368 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1369 stats->capabilities) ||
1370 nla_put_u32(vendor_event,
1371 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1372 stats->numRate))
1373 {
1374 hddLog(VOS_TRACE_LEVEL_ERROR,
1375 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1376 goto error;
1377 }
1378
1379 rateInfo = nla_nest_start(vendor_event,
1380 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301381 if(!rateInfo)
1382 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301383 for (i = 0; i < stats->numRate; i++)
1384 {
1385 struct nlattr *rates;
1386 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1387 stats->rateStats +
1388 (i * sizeof(tSirWifiRateStat)));
1389 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301390 if(!rates)
1391 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301392
1393 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1394 {
1395 hddLog(VOS_TRACE_LEVEL_ERROR,
1396 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1397 return FALSE;
1398 }
1399 nla_nest_end(vendor_event, rates);
1400 }
1401 nla_nest_end(vendor_event, rateInfo);
1402
1403 return TRUE;
1404error:
1405 return FALSE;
1406}
1407
1408static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1409 struct sk_buff *vendor_event)
1410{
1411 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1412 stats->ac ) ||
1413 nla_put_u32(vendor_event,
1414 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1415 stats->txMpdu ) ||
1416 nla_put_u32(vendor_event,
1417 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1418 stats->rxMpdu ) ||
1419 nla_put_u32(vendor_event,
1420 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1421 stats->txMcast ) ||
1422 nla_put_u32(vendor_event,
1423 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1424 stats->rxMcast ) ||
1425 nla_put_u32(vendor_event,
1426 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1427 stats->rxAmpdu ) ||
1428 nla_put_u32(vendor_event,
1429 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1430 stats->txAmpdu ) ||
1431 nla_put_u32(vendor_event,
1432 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1433 stats->mpduLost )||
1434 nla_put_u32(vendor_event,
1435 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1436 stats->retries ) ||
1437 nla_put_u32(vendor_event,
1438 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1439 stats->retriesShort ) ||
1440 nla_put_u32(vendor_event,
1441 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1442 stats->retriesLong ) ||
1443 nla_put_u32(vendor_event,
1444 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1445 stats->contentionTimeMin ) ||
1446 nla_put_u32(vendor_event,
1447 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1448 stats->contentionTimeMax ) ||
1449 nla_put_u32(vendor_event,
1450 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1451 stats->contentionTimeAvg ) ||
1452 nla_put_u32(vendor_event,
1453 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1454 stats->contentionNumSamples ))
1455 {
1456 hddLog(VOS_TRACE_LEVEL_ERROR,
1457 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1458 return FALSE;
1459 }
1460 return TRUE;
1461}
1462
1463static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1464 struct sk_buff *vendor_event)
1465{
Dino Myclec8f3f332014-07-21 16:48:27 +05301466 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301467 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1468 nla_put(vendor_event,
1469 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
1470 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
1471 nla_put_u32(vendor_event,
1472 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
1473 stats->state ) ||
1474 nla_put_u32(vendor_event,
1475 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
1476 stats->roaming ) ||
1477 nla_put_u32(vendor_event,
1478 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
1479 stats->capabilities ) ||
1480 nla_put(vendor_event,
1481 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
1482 strlen(stats->ssid), stats->ssid) ||
1483 nla_put(vendor_event,
1484 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
1485 WNI_CFG_BSSID_LEN, stats->bssid) ||
1486 nla_put(vendor_event,
1487 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
1488 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
1489 nla_put(vendor_event,
1490 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
1491 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
1492 )
1493 {
1494 hddLog(VOS_TRACE_LEVEL_ERROR,
1495 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1496 return FALSE;
1497 }
1498 return TRUE;
1499}
1500
Dino Mycle3b9536d2014-07-09 22:05:24 +05301501static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
1502 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301503 struct sk_buff *vendor_event)
1504{
1505 int i = 0;
1506 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301507 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1508 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301509 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301510
Sunil Duttc69bccb2014-05-26 21:30:20 +05301511 if (FALSE == put_wifi_interface_info(
1512 &pWifiIfaceStat->info,
1513 vendor_event))
1514 {
1515 hddLog(VOS_TRACE_LEVEL_ERROR,
1516 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1517 return FALSE;
1518
1519 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05301520 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
1521 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
1522 if (NULL == pWifiIfaceStatTL)
1523 {
1524 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1525 return FALSE;
1526 }
1527
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301528 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1529 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1530 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1531 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1532
1533 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1534 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1535 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1536 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301537
1538 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1539 {
1540 if (VOS_STATUS_SUCCESS ==
1541 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1542 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1543 {
1544 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1545 * obtained from TL structure
1546 */
1547
1548 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1549 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301550 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1551
Srinivas Dasari98947432014-11-07 19:41:24 +05301552 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1553 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1554 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1555 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1556 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1557 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1558 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1559 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301560
Srinivas Dasari98947432014-11-07 19:41:24 +05301561 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1562 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1563 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1564 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1565 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1566 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1567 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1568 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301569
Srinivas Dasari98947432014-11-07 19:41:24 +05301570 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1571 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1572 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1573 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1574 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1575 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1576 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1577 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301578 }
1579 else
1580 {
1581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1582 }
1583
Dino Mycle3b9536d2014-07-09 22:05:24 +05301584 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1585 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1586 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1587 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1588 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1589 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1590 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1591 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1592 }
1593 else
1594 {
1595 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1596 }
1597
1598
Sunil Duttc69bccb2014-05-26 21:30:20 +05301599
1600 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301601 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1602 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1603 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301604 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1605 pWifiIfaceStat->beaconRx) ||
1606 nla_put_u32(vendor_event,
1607 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1608 pWifiIfaceStat->mgmtRx) ||
1609 nla_put_u32(vendor_event,
1610 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1611 pWifiIfaceStat->mgmtActionRx) ||
1612 nla_put_u32(vendor_event,
1613 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1614 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301615 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301616 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1617 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301618 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301619 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1620 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301621 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301622 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1623 pWifiIfaceStat->rssiAck))
1624 {
1625 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301626 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1627 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301628 return FALSE;
1629 }
1630
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301631#ifdef FEATURE_EXT_LL_STAT
1632 /*
1633 * Ensure when EXT_LL_STAT is supported by both host and fwr,
1634 * then host should send Leaky AP stats to upper layer,
1635 * otherwise no need to send these stats.
1636 */
1637 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
1638 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
1639 )
1640 {
1641 hddLog(VOS_TRACE_LEVEL_INFO,
1642 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
1643 pWifiIfaceStat->leakyApStat.is_leaky_ap,
1644 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
1645 pWifiIfaceStat->leakyApStat.rx_leak_window,
1646 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
1647 if (nla_put_u32(vendor_event,
1648 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
1649 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
1650 nla_put_u32(vendor_event,
1651 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
1652 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
1653 nla_put_u32(vendor_event,
1654 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
1655 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
1656 nla_put_u64(vendor_event,
1657 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
1658 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
1659 {
1660 hddLog(VOS_TRACE_LEVEL_ERROR,
1661 FL("EXT_LL_STAT put fail"));
1662 vos_mem_free(pWifiIfaceStatTL);
1663 return FALSE;
1664 }
1665 }
1666#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301667 wmmInfo = nla_nest_start(vendor_event,
1668 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301669 if(!wmmInfo)
1670 {
1671 vos_mem_free(pWifiIfaceStatTL);
1672 return FALSE;
1673 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301674 for (i = 0; i < WIFI_AC_MAX; i++)
1675 {
1676 struct nlattr *wmmStats;
1677 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301678 if(!wmmStats)
1679 {
1680 vos_mem_free(pWifiIfaceStatTL);
1681 return FALSE;
1682 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301683 if (FALSE == put_wifi_wmm_ac_stat(
1684 &pWifiIfaceStat->AccessclassStats[i],
1685 vendor_event))
1686 {
1687 hddLog(VOS_TRACE_LEVEL_ERROR,
1688 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301689 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301690 return FALSE;
1691 }
1692
1693 nla_nest_end(vendor_event, wmmStats);
1694 }
1695 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301696 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301697 return TRUE;
1698}
1699
1700static tSirWifiInterfaceMode
1701 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1702{
1703 switch (deviceMode)
1704 {
1705 case WLAN_HDD_INFRA_STATION:
1706 return WIFI_INTERFACE_STA;
1707 case WLAN_HDD_SOFTAP:
1708 return WIFI_INTERFACE_SOFTAP;
1709 case WLAN_HDD_P2P_CLIENT:
1710 return WIFI_INTERFACE_P2P_CLIENT;
1711 case WLAN_HDD_P2P_GO:
1712 return WIFI_INTERFACE_P2P_GO;
1713 case WLAN_HDD_IBSS:
1714 return WIFI_INTERFACE_IBSS;
1715 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301716 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301717 }
1718}
1719
1720static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1721 tpSirWifiInterfaceInfo pInfo)
1722{
1723 v_U8_t *staMac = NULL;
1724 hdd_station_ctx_t *pHddStaCtx;
1725 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1726 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1727
1728 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1729
1730 vos_mem_copy(pInfo->macAddr,
1731 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1732
1733 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1734 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1735 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1736 {
1737 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1738 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1739 {
1740 pInfo->state = WIFI_DISCONNECTED;
1741 }
1742 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1743 {
1744 hddLog(VOS_TRACE_LEVEL_ERROR,
1745 "%s: Session ID %d, Connection is in progress", __func__,
1746 pAdapter->sessionId);
1747 pInfo->state = WIFI_ASSOCIATING;
1748 }
1749 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1750 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1751 {
1752 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1753 hddLog(VOS_TRACE_LEVEL_ERROR,
1754 "%s: client " MAC_ADDRESS_STR
1755 " is in the middle of WPS/EAPOL exchange.", __func__,
1756 MAC_ADDR_ARRAY(staMac));
1757 pInfo->state = WIFI_AUTHENTICATING;
1758 }
1759 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1760 {
1761 pInfo->state = WIFI_ASSOCIATED;
1762 vos_mem_copy(pInfo->bssid,
1763 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1764 vos_mem_copy(pInfo->ssid,
1765 pHddStaCtx->conn_info.SSID.SSID.ssId,
1766 pHddStaCtx->conn_info.SSID.SSID.length);
1767 //NULL Terminate the string.
1768 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1769 }
1770 }
1771 vos_mem_copy(pInfo->countryStr,
1772 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1773
1774 vos_mem_copy(pInfo->apCountryStr,
1775 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1776
1777 return TRUE;
1778}
1779
1780/*
1781 * hdd_link_layer_process_peer_stats () - This function is called after
1782 * receiving Link Layer Peer statistics from FW.This function converts
1783 * the firmware data to the NL data and sends the same to the kernel/upper
1784 * layers.
1785 */
1786static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1787 v_VOID_t *pData)
1788{
1789 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301790 tpSirWifiPeerStat pWifiPeerStat;
1791 tpSirWifiPeerInfo pWifiPeerInfo;
1792 struct nlattr *peerInfo;
1793 struct sk_buff *vendor_event;
1794 int status, i;
1795
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301796 ENTER();
1797
Sunil Duttc69bccb2014-05-26 21:30:20 +05301798 status = wlan_hdd_validate_context(pHddCtx);
1799 if (0 != status)
1800 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301801 return;
1802 }
1803
1804 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1805
1806 hddLog(VOS_TRACE_LEVEL_INFO,
1807 "LL_STATS_PEER_ALL : numPeers %u",
1808 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301809 /*
1810 * Allocate a size of 4096 for the peer stats comprising
1811 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1812 * sizeof (tSirWifiRateStat).Each field is put with an
1813 * NL attribute.The size of 4096 is considered assuming
1814 * that number of rates shall not exceed beyond 50 with
1815 * the sizeof (tSirWifiRateStat) being 32.
1816 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301817 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1818 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301819 if (!vendor_event)
1820 {
1821 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301822 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301823 __func__);
1824 return;
1825 }
1826 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301827 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1828 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1829 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301830 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1831 pWifiPeerStat->numPeers))
1832 {
1833 hddLog(VOS_TRACE_LEVEL_ERROR,
1834 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1835 kfree_skb(vendor_event);
1836 return;
1837 }
1838
1839 peerInfo = nla_nest_start(vendor_event,
1840 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301841 if(!peerInfo)
1842 {
1843 hddLog(VOS_TRACE_LEVEL_ERROR,
1844 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1845 __func__);
1846 kfree_skb(vendor_event);
1847 return;
1848 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301849
1850 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1851 pWifiPeerStat->peerInfo);
1852
1853 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1854 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301855 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301856 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301857
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301858 if(!peers)
1859 {
1860 hddLog(VOS_TRACE_LEVEL_ERROR,
1861 "%s: peer stats put fail",
1862 __func__);
1863 kfree_skb(vendor_event);
1864 return;
1865 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301866 if (FALSE == put_wifi_peer_info(
1867 pWifiPeerInfo, vendor_event))
1868 {
1869 hddLog(VOS_TRACE_LEVEL_ERROR,
1870 "%s: put_wifi_peer_info put fail", __func__);
1871 kfree_skb(vendor_event);
1872 return;
1873 }
1874
1875 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1876 pWifiPeerStat->peerInfo +
1877 (i * sizeof(tSirWifiPeerInfo)) +
1878 (numRate * sizeof (tSirWifiRateStat)));
1879 nla_nest_end(vendor_event, peers);
1880 }
1881 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301882 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301883 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301884}
1885
1886/*
1887 * hdd_link_layer_process_iface_stats () - This function is called after
1888 * receiving Link Layer Interface statistics from FW.This function converts
1889 * the firmware data to the NL data and sends the same to the kernel/upper
1890 * layers.
1891 */
1892static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1893 v_VOID_t *pData)
1894{
1895 tpSirWifiIfaceStat pWifiIfaceStat;
1896 struct sk_buff *vendor_event;
1897 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1898 int status;
1899
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301900 ENTER();
1901
Sunil Duttc69bccb2014-05-26 21:30:20 +05301902 status = wlan_hdd_validate_context(pHddCtx);
1903 if (0 != status)
1904 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301905 return;
1906 }
1907 /*
1908 * Allocate a size of 4096 for the interface stats comprising
1909 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1910 * assuming that all these fit with in the limit.Please take
1911 * a call on the limit based on the data requirements on
1912 * interface statistics.
1913 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301914 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1915 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301916 if (!vendor_event)
1917 {
1918 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301919 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301920 return;
1921 }
1922
1923 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1924
Dino Mycle3b9536d2014-07-09 22:05:24 +05301925
1926 if (FALSE == hdd_get_interface_info( pAdapter,
1927 &pWifiIfaceStat->info))
1928 {
1929 hddLog(VOS_TRACE_LEVEL_ERROR,
1930 FL("hdd_get_interface_info get fail") );
1931 kfree_skb(vendor_event);
1932 return;
1933 }
1934
1935 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1936 vendor_event))
1937 {
1938 hddLog(VOS_TRACE_LEVEL_ERROR,
1939 FL("put_wifi_iface_stats fail") );
1940 kfree_skb(vendor_event);
1941 return;
1942 }
1943
Sunil Duttc69bccb2014-05-26 21:30:20 +05301944 hddLog(VOS_TRACE_LEVEL_INFO,
1945 "WMI_LINK_STATS_IFACE Data");
1946
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301947 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301948
1949 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301950}
1951
1952/*
1953 * hdd_link_layer_process_radio_stats () - This function is called after
1954 * receiving Link Layer Radio statistics from FW.This function converts
1955 * the firmware data to the NL data and sends the same to the kernel/upper
1956 * layers.
1957 */
1958static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1959 v_VOID_t *pData)
1960{
1961 int status, i;
1962 tpSirWifiRadioStat pWifiRadioStat;
1963 tpSirWifiChannelStats pWifiChannelStats;
1964 struct sk_buff *vendor_event;
1965 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1966 struct nlattr *chList;
1967
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301968 ENTER();
1969
Sunil Duttc69bccb2014-05-26 21:30:20 +05301970 status = wlan_hdd_validate_context(pHddCtx);
1971 if (0 != status)
1972 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301973 return;
1974 }
1975 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1976
1977 hddLog(VOS_TRACE_LEVEL_INFO,
1978 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301979 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05301980 " radio is %d onTime is %u "
1981 " txTime is %u rxTime is %u "
1982 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301983 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301984 " onTimePnoScan is %u onTimeHs20 is %u "
1985 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301986 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301987 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1988 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1989 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301990 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301991 pWifiRadioStat->onTimeRoamScan,
1992 pWifiRadioStat->onTimePnoScan,
1993 pWifiRadioStat->onTimeHs20,
1994 pWifiRadioStat->numChannels);
1995 /*
1996 * Allocate a size of 4096 for the Radio stats comprising
1997 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1998 * (tSirWifiChannelStats).Each channel data is put with an
1999 * NL attribute.The size of 4096 is considered assuming that
2000 * number of channels shall not exceed beyond 60 with the
2001 * sizeof (tSirWifiChannelStats) being 24 bytes.
2002 */
2003
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302004 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2005 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302006 if (!vendor_event)
2007 {
2008 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302009 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302010 return;
2011 }
2012
2013 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302014 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2015 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2016 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302017 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2018 pWifiRadioStat->radio) ||
2019 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302020 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2021 NUM_RADIOS) ||
2022 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302023 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2024 pWifiRadioStat->onTime) ||
2025 nla_put_u32(vendor_event,
2026 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2027 pWifiRadioStat->txTime) ||
2028 nla_put_u32(vendor_event,
2029 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2030 pWifiRadioStat->rxTime) ||
2031 nla_put_u32(vendor_event,
2032 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2033 pWifiRadioStat->onTimeScan) ||
2034 nla_put_u32(vendor_event,
2035 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2036 pWifiRadioStat->onTimeNbd) ||
2037 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302038 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2039 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302040 nla_put_u32(vendor_event,
2041 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2042 pWifiRadioStat->onTimeRoamScan) ||
2043 nla_put_u32(vendor_event,
2044 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2045 pWifiRadioStat->onTimePnoScan) ||
2046 nla_put_u32(vendor_event,
2047 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2048 pWifiRadioStat->onTimeHs20) ||
2049 nla_put_u32(vendor_event,
2050 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2051 pWifiRadioStat->numChannels))
2052 {
2053 hddLog(VOS_TRACE_LEVEL_ERROR,
2054 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2055 kfree_skb(vendor_event);
2056 return ;
2057 }
2058
2059 chList = nla_nest_start(vendor_event,
2060 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302061 if(!chList)
2062 {
2063 hddLog(VOS_TRACE_LEVEL_ERROR,
2064 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2065 __func__);
2066 kfree_skb(vendor_event);
2067 return;
2068 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302069 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2070 {
2071 struct nlattr *chInfo;
2072
2073 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2074 pWifiRadioStat->channels +
2075 (i * sizeof(tSirWifiChannelStats)));
2076
Sunil Duttc69bccb2014-05-26 21:30:20 +05302077 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302078 if(!chInfo)
2079 {
2080 hddLog(VOS_TRACE_LEVEL_ERROR,
2081 "%s: failed to put chInfo",
2082 __func__);
2083 kfree_skb(vendor_event);
2084 return;
2085 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302086
2087 if (nla_put_u32(vendor_event,
2088 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2089 pWifiChannelStats->channel.width) ||
2090 nla_put_u32(vendor_event,
2091 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2092 pWifiChannelStats->channel.centerFreq) ||
2093 nla_put_u32(vendor_event,
2094 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2095 pWifiChannelStats->channel.centerFreq0) ||
2096 nla_put_u32(vendor_event,
2097 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2098 pWifiChannelStats->channel.centerFreq1) ||
2099 nla_put_u32(vendor_event,
2100 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2101 pWifiChannelStats->onTime) ||
2102 nla_put_u32(vendor_event,
2103 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2104 pWifiChannelStats->ccaBusyTime))
2105 {
2106 hddLog(VOS_TRACE_LEVEL_ERROR,
2107 FL("cfg80211_vendor_event_alloc failed") );
2108 kfree_skb(vendor_event);
2109 return ;
2110 }
2111 nla_nest_end(vendor_event, chInfo);
2112 }
2113 nla_nest_end(vendor_event, chList);
2114
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302115 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302116
2117 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302118 return;
2119}
2120
2121/*
2122 * hdd_link_layer_stats_ind_callback () - This function is called after
2123 * receiving Link Layer indications from FW.This callback converts the firmware
2124 * data to the NL data and send the same to the kernel/upper layers.
2125 */
2126static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2127 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302128 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302129{
Dino Mycled3d50022014-07-07 12:58:25 +05302130 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2131 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302132 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302133 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302134 int status;
2135
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302136 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302137
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302138 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302139 if (0 != status)
2140 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302141 return;
2142 }
2143
Dino Mycled3d50022014-07-07 12:58:25 +05302144 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2145 if (NULL == pAdapter)
2146 {
2147 hddLog(VOS_TRACE_LEVEL_ERROR,
2148 FL(" MAC address %pM does not exist with host"),
2149 macAddr);
2150 return;
2151 }
2152
Sunil Duttc69bccb2014-05-26 21:30:20 +05302153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302154 "%s: Interface: %s LLStats indType: %d", __func__,
2155 pAdapter->dev->name, indType);
2156
Sunil Duttc69bccb2014-05-26 21:30:20 +05302157 switch (indType)
2158 {
2159 case SIR_HAL_LL_STATS_RESULTS_RSP:
2160 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302161 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302162 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2163 "respId = %u, moreResultToFollow = %u",
2164 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2165 macAddr, linkLayerStatsResults->respId,
2166 linkLayerStatsResults->moreResultToFollow);
2167
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302168 spin_lock(&hdd_context_lock);
2169 context = &pHddCtx->ll_stats_context;
2170 /* validate response received from target */
2171 if ((context->request_id != linkLayerStatsResults->respId) ||
2172 !(context->request_bitmap & linkLayerStatsResults->paramId))
2173 {
2174 spin_unlock(&hdd_context_lock);
2175 hddLog(LOGE,
2176 FL("Error : Request id %d response id %d request bitmap 0x%x"
2177 "response bitmap 0x%x"),
2178 context->request_id, linkLayerStatsResults->respId,
2179 context->request_bitmap, linkLayerStatsResults->paramId);
2180 return;
2181 }
2182 spin_unlock(&hdd_context_lock);
2183
Sunil Duttc69bccb2014-05-26 21:30:20 +05302184 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2185 {
2186 hdd_link_layer_process_radio_stats(pAdapter,
2187 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302188 spin_lock(&hdd_context_lock);
2189 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2190 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302191 }
2192 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2193 {
2194 hdd_link_layer_process_iface_stats(pAdapter,
2195 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302196 spin_lock(&hdd_context_lock);
2197 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2198 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302199 }
2200 else if ( linkLayerStatsResults->paramId &
2201 WMI_LINK_STATS_ALL_PEER )
2202 {
2203 hdd_link_layer_process_peer_stats(pAdapter,
2204 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302205 spin_lock(&hdd_context_lock);
2206 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2207 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302208 } /* WMI_LINK_STATS_ALL_PEER */
2209 else
2210 {
2211 hddLog(VOS_TRACE_LEVEL_ERROR,
2212 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2213 }
2214
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302215 spin_lock(&hdd_context_lock);
2216 /* complete response event if all requests are completed */
2217 if (0 == context->request_bitmap)
2218 complete(&context->response_event);
2219 spin_unlock(&hdd_context_lock);
2220
Sunil Duttc69bccb2014-05-26 21:30:20 +05302221 break;
2222 }
2223 default:
2224 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2225 break;
2226 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302227
2228 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302229 return;
2230}
2231
2232const struct
2233nla_policy
2234qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2235{
2236 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2237 { .type = NLA_U32 },
2238 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2239 { .type = NLA_U32 },
2240};
2241
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302242static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2243 struct wireless_dev *wdev,
2244 const void *data,
2245 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302246{
2247 int status;
2248 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302249 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302250 struct net_device *dev = wdev->netdev;
2251 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2252 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2253
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302254 ENTER();
2255
Sunil Duttc69bccb2014-05-26 21:30:20 +05302256 status = wlan_hdd_validate_context(pHddCtx);
2257 if (0 != status)
2258 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302259 return -EINVAL;
2260 }
2261
2262 if (NULL == pAdapter)
2263 {
2264 hddLog(VOS_TRACE_LEVEL_ERROR,
2265 FL("HDD adapter is Null"));
2266 return -ENODEV;
2267 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302268 /* check the LLStats Capability */
2269 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2270 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2271 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302272 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302273 FL("Link Layer Statistics not supported by Firmware"));
2274 return -EINVAL;
2275 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302276
2277 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2278 (struct nlattr *)data,
2279 data_len, qca_wlan_vendor_ll_set_policy))
2280 {
2281 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2282 return -EINVAL;
2283 }
2284 if (!tb_vendor
2285 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2286 {
2287 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2288 return -EINVAL;
2289 }
2290 if (!tb_vendor[
2291 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2292 {
2293 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2294 return -EINVAL;
2295 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302296 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302297 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302298
Dino Mycledf0a5d92014-07-04 09:41:55 +05302299 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302300 nla_get_u32(
2301 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2302
Dino Mycledf0a5d92014-07-04 09:41:55 +05302303 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302304 nla_get_u32(
2305 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2306
Dino Mycled3d50022014-07-07 12:58:25 +05302307 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2308 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302309
2310
2311 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302312 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2313 "Statistics Gathering = %d ",
2314 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2315 linkLayerStatsSetReq.mpduSizeThreshold,
2316 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302317
2318 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2319 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302320 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302321 {
2322 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2323 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302324 return -EINVAL;
2325
2326 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302327
Sunil Duttc69bccb2014-05-26 21:30:20 +05302328 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302329 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302330 {
2331 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2332 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302333 return -EINVAL;
2334 }
2335
2336 pAdapter->isLinkLayerStatsSet = 1;
2337
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302338 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302339 return 0;
2340}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302341static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2342 struct wireless_dev *wdev,
2343 const void *data,
2344 int data_len)
2345{
2346 int ret = 0;
2347
2348 vos_ssr_protect(__func__);
2349 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2350 vos_ssr_unprotect(__func__);
2351
2352 return ret;
2353}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302354
2355const struct
2356nla_policy
2357qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2358{
2359 /* Unsigned 32bit value provided by the caller issuing the GET stats
2360 * command. When reporting
2361 * the stats results, the driver uses the same value to indicate
2362 * which GET request the results
2363 * correspond to.
2364 */
2365 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2366
2367 /* Unsigned 32bit value . bit mask to identify what statistics are
2368 requested for retrieval */
2369 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2370};
2371
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302372static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2373 struct wireless_dev *wdev,
2374 const void *data,
2375 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302376{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302377 unsigned long rc;
2378 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302379 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2380 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302381 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302382 struct net_device *dev = wdev->netdev;
2383 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302384 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302385 int status;
2386
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302387 ENTER();
2388
Sunil Duttc69bccb2014-05-26 21:30:20 +05302389 status = wlan_hdd_validate_context(pHddCtx);
2390 if (0 != status)
2391 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302392 return -EINVAL ;
2393 }
2394
2395 if (NULL == pAdapter)
2396 {
2397 hddLog(VOS_TRACE_LEVEL_FATAL,
2398 "%s: HDD adapter is Null", __func__);
2399 return -ENODEV;
2400 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302401
2402 if (pHddStaCtx == NULL)
2403 {
2404 hddLog(VOS_TRACE_LEVEL_FATAL,
2405 "%s: HddStaCtx is Null", __func__);
2406 return -ENODEV;
2407 }
2408
Dino Mycledf0a5d92014-07-04 09:41:55 +05302409 /* check the LLStats Capability */
2410 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2411 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2412 {
2413 hddLog(VOS_TRACE_LEVEL_ERROR,
2414 FL("Link Layer Statistics not supported by Firmware"));
2415 return -EINVAL;
2416 }
2417
Sunil Duttc69bccb2014-05-26 21:30:20 +05302418
2419 if (!pAdapter->isLinkLayerStatsSet)
2420 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302421 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302422 "%s: isLinkLayerStatsSet : %d",
2423 __func__, pAdapter->isLinkLayerStatsSet);
2424 return -EINVAL;
2425 }
2426
Mukul Sharma10313ba2015-07-29 19:14:39 +05302427 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2428 {
2429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2430 "%s: Roaming in progress, so unable to proceed this request", __func__);
2431 return -EBUSY;
2432 }
2433
Sunil Duttc69bccb2014-05-26 21:30:20 +05302434 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2435 (struct nlattr *)data,
2436 data_len, qca_wlan_vendor_ll_get_policy))
2437 {
2438 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2439 return -EINVAL;
2440 }
2441
2442 if (!tb_vendor
2443 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2444 {
2445 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2446 return -EINVAL;
2447 }
2448
2449 if (!tb_vendor
2450 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2451 {
2452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2453 return -EINVAL;
2454 }
2455
Sunil Duttc69bccb2014-05-26 21:30:20 +05302456
Dino Mycledf0a5d92014-07-04 09:41:55 +05302457 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302458 nla_get_u32( tb_vendor[
2459 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302460 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302461 nla_get_u32( tb_vendor[
2462 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2463
Dino Mycled3d50022014-07-07 12:58:25 +05302464 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2465 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302466
2467 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302468 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2469 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302470 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302471
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302472 spin_lock(&hdd_context_lock);
2473 context = &pHddCtx->ll_stats_context;
2474 context->request_id = linkLayerStatsGetReq.reqId;
2475 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
2476 INIT_COMPLETION(context->response_event);
2477 spin_unlock(&hdd_context_lock);
2478
Sunil Duttc69bccb2014-05-26 21:30:20 +05302479 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302480 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302481 {
2482 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2483 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302484 return -EINVAL;
2485 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302486
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302487 rc = wait_for_completion_timeout(&context->response_event,
2488 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
2489 if (!rc)
2490 {
2491 hddLog(LOGE,
2492 FL("Target response timed out request id %d request bitmap 0x%x"),
2493 context->request_id, context->request_bitmap);
2494 return -ETIMEDOUT;
2495 }
2496
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302497 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302498 return 0;
2499}
2500
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302501static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2502 struct wireless_dev *wdev,
2503 const void *data,
2504 int data_len)
2505{
2506 int ret = 0;
2507
2508 vos_ssr_protect(__func__);
2509 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2510 vos_ssr_unprotect(__func__);
2511
2512 return ret;
2513}
2514
Sunil Duttc69bccb2014-05-26 21:30:20 +05302515const struct
2516nla_policy
2517qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2518{
2519 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2520 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2521 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2522 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2523};
2524
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302525static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2526 struct wireless_dev *wdev,
2527 const void *data,
2528 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302529{
2530 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2531 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302532 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302533 struct net_device *dev = wdev->netdev;
2534 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2535 u32 statsClearReqMask;
2536 u8 stopReq;
2537 int status;
2538
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302539 ENTER();
2540
Sunil Duttc69bccb2014-05-26 21:30:20 +05302541 status = wlan_hdd_validate_context(pHddCtx);
2542 if (0 != status)
2543 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302544 return -EINVAL;
2545 }
2546
2547 if (NULL == pAdapter)
2548 {
2549 hddLog(VOS_TRACE_LEVEL_FATAL,
2550 "%s: HDD adapter is Null", __func__);
2551 return -ENODEV;
2552 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302553 /* check the LLStats Capability */
2554 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2555 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2556 {
2557 hddLog(VOS_TRACE_LEVEL_ERROR,
2558 FL("Enable LLStats Capability"));
2559 return -EINVAL;
2560 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302561
2562 if (!pAdapter->isLinkLayerStatsSet)
2563 {
2564 hddLog(VOS_TRACE_LEVEL_FATAL,
2565 "%s: isLinkLayerStatsSet : %d",
2566 __func__, pAdapter->isLinkLayerStatsSet);
2567 return -EINVAL;
2568 }
2569
2570 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2571 (struct nlattr *)data,
2572 data_len, qca_wlan_vendor_ll_clr_policy))
2573 {
2574 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2575 return -EINVAL;
2576 }
2577
2578 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2579
2580 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2581 {
2582 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2583 return -EINVAL;
2584
2585 }
2586
Sunil Duttc69bccb2014-05-26 21:30:20 +05302587
Dino Mycledf0a5d92014-07-04 09:41:55 +05302588 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302589 nla_get_u32(
2590 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2591
Dino Mycledf0a5d92014-07-04 09:41:55 +05302592 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302593 nla_get_u8(
2594 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2595
2596 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302597 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302598
Dino Mycled3d50022014-07-07 12:58:25 +05302599 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2600 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302601
2602 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302603 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2604 "statsClearReqMask = 0x%X, stopReq = %d",
2605 linkLayerStatsClearReq.reqId,
2606 linkLayerStatsClearReq.macAddr,
2607 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302608 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302609
2610 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302611 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302612 {
2613 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302614 hdd_station_ctx_t *pHddStaCtx;
2615
2616 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2617 if (VOS_STATUS_SUCCESS !=
2618 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2619 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2620 {
2621 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2622 "WLANTL_ClearInterfaceStats Failed", __func__);
2623 return -EINVAL;
2624 }
2625 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2626 (statsClearReqMask & WIFI_STATS_IFACE)) {
2627 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2628 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2629 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2630 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2631 }
2632
Sunil Duttc69bccb2014-05-26 21:30:20 +05302633 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2634 2 * sizeof(u32) +
2635 NLMSG_HDRLEN);
2636
2637 if (temp_skbuff != NULL)
2638 {
2639
2640 if (nla_put_u32(temp_skbuff,
2641 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2642 statsClearReqMask) ||
2643 nla_put_u32(temp_skbuff,
2644 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2645 stopReq))
2646 {
2647 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2648 kfree_skb(temp_skbuff);
2649 return -EINVAL;
2650 }
2651 /* If the ask is to stop the stats collection as part of clear
2652 * (stopReq = 1) , ensure that no further requests of get
2653 * go to the firmware by having isLinkLayerStatsSet set to 0.
2654 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302655 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302656 * case the firmware is just asked to clear the statistics.
2657 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302658 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302659 pAdapter->isLinkLayerStatsSet = 0;
2660 return cfg80211_vendor_cmd_reply(temp_skbuff);
2661 }
2662 return -ENOMEM;
2663 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302664
2665 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302666 return -EINVAL;
2667}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302668static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2669 struct wireless_dev *wdev,
2670 const void *data,
2671 int data_len)
2672{
2673 int ret = 0;
2674
2675 vos_ssr_protect(__func__);
2676 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2677 vos_ssr_unprotect(__func__);
2678
2679 return ret;
2680
2681
2682}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302683#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2684
Dino Mycle6fb96c12014-06-10 11:52:40 +05302685#ifdef WLAN_FEATURE_EXTSCAN
2686static const struct nla_policy
2687wlan_hdd_extscan_config_policy
2688 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2689{
2690 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2691 { .type = NLA_U32 },
2692 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2693 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05302694 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
2695 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302696 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2697 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2698 { .type = NLA_U32 },
2699 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2700 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2701
2702 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2703 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2704 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2705 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2706 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302707 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2708 { .type = NLA_U32 },
2709 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2710 { .type = NLA_U32 },
2711 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2712 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302713 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2714 { .type = NLA_U32 },
2715 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2716 { .type = NLA_U32 },
2717 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2718 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302719 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2720 { .type = NLA_U8 },
2721 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302722 { .type = NLA_U8 },
2723 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2724 { .type = NLA_U8 },
2725 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2726 { .type = NLA_U8 },
2727
2728 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2729 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05302730 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
2731 .type = NLA_UNSPEC,
2732 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05302733 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2734 { .type = NLA_S32 },
2735 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2736 { .type = NLA_S32 },
2737 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2738 { .type = NLA_U32 },
2739 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2740 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302741 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2742 { .type = NLA_U32 },
2743 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2744 { .type = NLA_BINARY,
2745 .len = IEEE80211_MAX_SSID_LEN + 1 },
2746 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302747 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302748 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2749 { .type = NLA_U32 },
2750 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2751 { .type = NLA_U8 },
2752 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2753 { .type = NLA_S32 },
2754 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2755 { .type = NLA_S32 },
2756 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2757 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302758};
2759
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302760/**
2761 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2762 * @ctx: hdd global context
2763 * @data: capabilities data
2764 *
2765 * Return: none
2766 */
2767static void
2768wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302769{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302770 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302771 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302772 tSirEXTScanCapabilitiesEvent *data =
2773 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302774
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302775 ENTER();
2776
2777 if (wlan_hdd_validate_context(pHddCtx))
2778 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302779 return;
2780 }
2781
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302782 if (!pMsg)
2783 {
2784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2785 return;
2786 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302787
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302788 vos_spin_lock_acquire(&hdd_context_lock);
2789
2790 context = &pHddCtx->ext_scan_context;
2791 /* validate response received from target*/
2792 if (context->request_id != data->requestId)
2793 {
2794 vos_spin_lock_release(&hdd_context_lock);
2795 hddLog(LOGE,
2796 FL("Target response id did not match: request_id %d resposne_id %d"),
2797 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302798 return;
2799 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302800 else
2801 {
2802 context->capability_response = *data;
2803 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302804 }
2805
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302806 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302807
Dino Mycle6fb96c12014-06-10 11:52:40 +05302808 return;
2809}
2810
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302811/*
2812 * define short names for the global vendor params
2813 * used by wlan_hdd_send_ext_scan_capability()
2814 */
2815#define PARAM_REQUEST_ID \
2816 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2817#define PARAM_STATUS \
2818 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2819#define MAX_SCAN_CACHE_SIZE \
2820 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2821#define MAX_SCAN_BUCKETS \
2822 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2823#define MAX_AP_CACHE_PER_SCAN \
2824 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2825#define MAX_RSSI_SAMPLE_SIZE \
2826 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2827#define MAX_SCAN_RPT_THRHOLD \
2828 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2829#define MAX_HOTLIST_BSSIDS \
2830 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2831#define MAX_BSSID_HISTORY_ENTRIES \
2832 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2833#define MAX_HOTLIST_SSIDS \
2834 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302835#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2836 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302837
2838static int wlan_hdd_send_ext_scan_capability(void *ctx)
2839{
2840 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2841 struct sk_buff *skb = NULL;
2842 int ret;
2843 tSirEXTScanCapabilitiesEvent *data;
2844 tANI_U32 nl_buf_len;
2845
2846 ret = wlan_hdd_validate_context(pHddCtx);
2847 if (0 != ret)
2848 {
2849 return ret;
2850 }
2851
2852 data = &(pHddCtx->ext_scan_context.capability_response);
2853
2854 nl_buf_len = NLMSG_HDRLEN;
2855 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2856 (sizeof(data->status) + NLA_HDRLEN) +
2857 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2858 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2859 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2860 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2861 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2862 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2863 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2864 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2865
2866 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2867
2868 if (!skb)
2869 {
2870 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2871 return -ENOMEM;
2872 }
2873
2874 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2875 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2876 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2877 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2878 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2879 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2880 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2881 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2882
2883 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2884 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2885 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2886 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2887 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2888 data->maxApPerScan) ||
2889 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2890 data->maxRssiSampleSize) ||
2891 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2892 data->maxScanReportingThreshold) ||
2893 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2894 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2895 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302896 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2897 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302898 {
2899 hddLog(LOGE, FL("nla put fail"));
2900 goto nla_put_failure;
2901 }
2902
2903 cfg80211_vendor_cmd_reply(skb);
2904 return 0;
2905
2906nla_put_failure:
2907 kfree_skb(skb);
2908 return -EINVAL;;
2909}
2910
2911/*
2912 * done with short names for the global vendor params
2913 * used by wlan_hdd_send_ext_scan_capability()
2914 */
2915#undef PARAM_REQUEST_ID
2916#undef PARAM_STATUS
2917#undef MAX_SCAN_CACHE_SIZE
2918#undef MAX_SCAN_BUCKETS
2919#undef MAX_AP_CACHE_PER_SCAN
2920#undef MAX_RSSI_SAMPLE_SIZE
2921#undef MAX_SCAN_RPT_THRHOLD
2922#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302923#undef MAX_BSSID_HISTORY_ENTRIES
2924#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302925
2926static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2927{
2928 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2929 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302930 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302931 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302932
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302933 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302934
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302935 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302936 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302937
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302938 if (!pMsg)
2939 {
2940 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302941 return;
2942 }
2943
Dino Mycle6fb96c12014-06-10 11:52:40 +05302944 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2945 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2946
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302947 context = &pHddCtx->ext_scan_context;
2948 spin_lock(&hdd_context_lock);
2949 if (context->request_id == pData->requestId) {
2950 context->response_status = pData->status ? -EINVAL : 0;
2951 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302952 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302953 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302954
2955 /*
2956 * Store the Request ID for comparing with the requestID obtained
2957 * in other requests.HDD shall return a failure is the extscan_stop
2958 * request is issued with a different requestId as that of the
2959 * extscan_start request. Also, This requestId shall be used while
2960 * indicating the full scan results to the upper layers.
2961 * The requestId is stored with the assumption that the firmware
2962 * shall return the ext scan start request's requestId in ext scan
2963 * start response.
2964 */
2965 if (pData->status == 0)
2966 pMac->sme.extScanStartReqId = pData->requestId;
2967
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302968 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302969 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302970}
2971
2972
2973static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2974{
2975 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2976 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302977 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302978
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302979 ENTER();
2980
2981 if (wlan_hdd_validate_context(pHddCtx)){
2982 return;
2983 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302984
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302985 if (!pMsg)
2986 {
2987 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302988 return;
2989 }
2990
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302991 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2992 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302993
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302994 context = &pHddCtx->ext_scan_context;
2995 spin_lock(&hdd_context_lock);
2996 if (context->request_id == pData->requestId) {
2997 context->response_status = pData->status ? -EINVAL : 0;
2998 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302999 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303000 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303001
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303002 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303003 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303004}
3005
Dino Mycle6fb96c12014-06-10 11:52:40 +05303006static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3007 void *pMsg)
3008{
3009 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303010 tpSirEXTScanSetBssidHotListRspParams pData =
3011 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303012 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303013
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303014 ENTER();
3015
3016 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303017 return;
3018 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303019
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303020 if (!pMsg)
3021 {
3022 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3023 return;
3024 }
3025
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303026 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3027 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303028
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303029 context = &pHddCtx->ext_scan_context;
3030 spin_lock(&hdd_context_lock);
3031 if (context->request_id == pData->requestId) {
3032 context->response_status = pData->status ? -EINVAL : 0;
3033 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303034 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303035 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303036
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303037 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303038 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303039}
3040
3041static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3042 void *pMsg)
3043{
3044 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303045 tpSirEXTScanResetBssidHotlistRspParams pData =
3046 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303047 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303048
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303049 ENTER();
3050
3051 if (wlan_hdd_validate_context(pHddCtx)) {
3052 return;
3053 }
3054 if (!pMsg)
3055 {
3056 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303057 return;
3058 }
3059
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303060 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3061 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303062
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303063 context = &pHddCtx->ext_scan_context;
3064 spin_lock(&hdd_context_lock);
3065 if (context->request_id == pData->requestId) {
3066 context->response_status = pData->status ? -EINVAL : 0;
3067 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303068 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303069 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303070
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303071 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303072 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303073}
3074
Dino Mycle6fb96c12014-06-10 11:52:40 +05303075static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3076 void *pMsg)
3077{
3078 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3079 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303080 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303081 tANI_S32 totalResults;
3082 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303083 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3084 struct hdd_ext_scan_context *context;
3085 bool ignore_cached_results = false;
3086 tExtscanCachedScanResult *result;
3087 struct nlattr *nla_results;
3088 tANI_U16 ieLength= 0;
3089 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303090
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303091 ENTER();
3092
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303093 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303094 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303095
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303096 if (!pMsg)
3097 {
3098 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3099 return;
3100 }
3101
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303102 spin_lock(&hdd_context_lock);
3103 context = &pHddCtx->ext_scan_context;
3104 ignore_cached_results = context->ignore_cached_results;
3105 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303106
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303107 if (ignore_cached_results) {
3108 hddLog(LOGE,
3109 FL("Ignore the cached results received after timeout"));
3110 return;
3111 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303112
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303113 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3114 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303115
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303116 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303117
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303118 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3119 scan_id_index++) {
3120 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303121
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303122 totalResults = result->num_results;
3123 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3124 result->scan_id, result->flags, totalResults);
3125 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303126
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303127 do{
3128 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3129 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3130 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303131
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303132 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3133 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3134
3135 if (!skb) {
3136 hddLog(VOS_TRACE_LEVEL_ERROR,
3137 FL("cfg80211_vendor_event_alloc failed"));
3138 return;
3139 }
3140
3141 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3142
3143 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3144 pData->requestId) ||
3145 nla_put_u32(skb,
3146 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3147 resultsPerEvent)) {
3148 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3149 goto fail;
3150 }
3151 if (nla_put_u8(skb,
3152 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3153 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303154 {
3155 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3156 goto fail;
3157 }
3158
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303159 if (nla_put_u32(skb,
3160 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3161 result->scan_id)) {
3162 hddLog(LOGE, FL("put fail"));
3163 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303164 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303165
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303166 nla_results = nla_nest_start(skb,
3167 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3168 if (!nla_results)
3169 goto fail;
3170
3171 if (resultsPerEvent) {
3172 struct nlattr *aps;
3173 struct nlattr *nla_result;
3174
3175 nla_result = nla_nest_start(skb, scan_id_index);
3176 if(!nla_result)
3177 goto fail;
3178
3179 if (nla_put_u32(skb,
3180 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3181 result->scan_id) ||
3182 nla_put_u32(skb,
3183 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3184 result->flags) ||
3185 nla_put_u32(skb,
3186 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3187 totalResults)) {
3188 hddLog(LOGE, FL("put fail"));
3189 goto fail;
3190 }
3191
3192 aps = nla_nest_start(skb,
3193 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3194 if (!aps)
3195 {
3196 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3197 goto fail;
3198 }
3199
3200 head_ptr = (tpSirWifiScanResult) &(result->ap);
3201
3202 for (j = 0; j < resultsPerEvent; j++, i++) {
3203 struct nlattr *ap;
3204 pSirWifiScanResult = head_ptr + i;
3205
3206 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303207 * Firmware returns timestamp from extscan_start till
3208 * BSSID was cached (in micro seconds). Add this with
3209 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303210 * to derive the time since boot when the
3211 * BSSID was cached.
3212 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303213 pSirWifiScanResult->ts +=
3214 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303215 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3216 "Ssid (%s)"
3217 "Bssid: %pM "
3218 "Channel (%u)"
3219 "Rssi (%d)"
3220 "RTT (%u)"
3221 "RTT_SD (%u)"
3222 "Beacon Period %u"
3223 "Capability 0x%x "
3224 "Ie length %d",
3225 i,
3226 pSirWifiScanResult->ts,
3227 pSirWifiScanResult->ssid,
3228 pSirWifiScanResult->bssid,
3229 pSirWifiScanResult->channel,
3230 pSirWifiScanResult->rssi,
3231 pSirWifiScanResult->rtt,
3232 pSirWifiScanResult->rtt_sd,
3233 pSirWifiScanResult->beaconPeriod,
3234 pSirWifiScanResult->capability,
3235 ieLength);
3236
3237 ap = nla_nest_start(skb, j + 1);
3238 if (!ap)
3239 {
3240 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3241 goto fail;
3242 }
3243
3244 if (nla_put_u64(skb,
3245 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3246 pSirWifiScanResult->ts) )
3247 {
3248 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3249 goto fail;
3250 }
3251 if (nla_put(skb,
3252 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3253 sizeof(pSirWifiScanResult->ssid),
3254 pSirWifiScanResult->ssid) )
3255 {
3256 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3257 goto fail;
3258 }
3259 if (nla_put(skb,
3260 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3261 sizeof(pSirWifiScanResult->bssid),
3262 pSirWifiScanResult->bssid) )
3263 {
3264 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3265 goto fail;
3266 }
3267 if (nla_put_u32(skb,
3268 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3269 pSirWifiScanResult->channel) )
3270 {
3271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3272 goto fail;
3273 }
3274 if (nla_put_s32(skb,
3275 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3276 pSirWifiScanResult->rssi) )
3277 {
3278 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3279 goto fail;
3280 }
3281 if (nla_put_u32(skb,
3282 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3283 pSirWifiScanResult->rtt) )
3284 {
3285 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3286 goto fail;
3287 }
3288 if (nla_put_u32(skb,
3289 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3290 pSirWifiScanResult->rtt_sd))
3291 {
3292 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3293 goto fail;
3294 }
3295 if (nla_put_u32(skb,
3296 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3297 pSirWifiScanResult->beaconPeriod))
3298 {
3299 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3300 goto fail;
3301 }
3302 if (nla_put_u32(skb,
3303 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3304 pSirWifiScanResult->capability))
3305 {
3306 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3307 goto fail;
3308 }
3309 if (nla_put_u32(skb,
3310 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3311 ieLength))
3312 {
3313 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3314 goto fail;
3315 }
3316
3317 if (ieLength)
3318 if (nla_put(skb,
3319 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3320 ieLength, ie)) {
3321 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3322 goto fail;
3323 }
3324
3325 nla_nest_end(skb, ap);
3326 }
3327 nla_nest_end(skb, aps);
3328 nla_nest_end(skb, nla_result);
3329 }
3330
3331 nla_nest_end(skb, nla_results);
3332
3333 cfg80211_vendor_cmd_reply(skb);
3334
3335 } while (totalResults > 0);
3336 }
3337
3338 if (!pData->moreData) {
3339 spin_lock(&hdd_context_lock);
3340 context->response_status = 0;
3341 complete(&context->response_event);
3342 spin_unlock(&hdd_context_lock);
3343 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303344
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303345 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303346 return;
3347fail:
3348 kfree_skb(skb);
3349 return;
3350}
3351
3352static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3353 void *pMsg)
3354{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303355 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303356 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3357 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303358 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303359
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303360 ENTER();
3361
3362 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303363 hddLog(LOGE,
3364 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303365 return;
3366 }
3367 if (!pMsg)
3368 {
3369 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303370 return;
3371 }
3372
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303373 if (pData->bss_found)
3374 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3375 else
3376 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3377
Dino Mycle6fb96c12014-06-10 11:52:40 +05303378 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303379#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3380 NULL,
3381#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303382 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303383 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303384
3385 if (!skb) {
3386 hddLog(VOS_TRACE_LEVEL_ERROR,
3387 FL("cfg80211_vendor_event_alloc failed"));
3388 return;
3389 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303390
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303391 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3392 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3393 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3394 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3395
3396 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303397 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3398 "Ssid (%s) "
3399 "Bssid (" MAC_ADDRESS_STR ") "
3400 "Channel (%u) "
3401 "Rssi (%d) "
3402 "RTT (%u) "
3403 "RTT_SD (%u) ",
3404 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303405 pData->bssHotlist[i].ts,
3406 pData->bssHotlist[i].ssid,
3407 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3408 pData->bssHotlist[i].channel,
3409 pData->bssHotlist[i].rssi,
3410 pData->bssHotlist[i].rtt,
3411 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303412 }
3413
3414 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3415 pData->requestId) ||
3416 nla_put_u32(skb,
3417 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303418 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303419 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3420 goto fail;
3421 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303422 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303423 struct nlattr *aps;
3424
3425 aps = nla_nest_start(skb,
3426 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3427 if (!aps)
3428 goto fail;
3429
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303430 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303431 struct nlattr *ap;
3432
3433 ap = nla_nest_start(skb, i + 1);
3434 if (!ap)
3435 goto fail;
3436
3437 if (nla_put_u64(skb,
3438 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303439 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303440 nla_put(skb,
3441 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303442 sizeof(pData->bssHotlist[i].ssid),
3443 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303444 nla_put(skb,
3445 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303446 sizeof(pData->bssHotlist[i].bssid),
3447 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303448 nla_put_u32(skb,
3449 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303450 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303451 nla_put_s32(skb,
3452 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303453 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303454 nla_put_u32(skb,
3455 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303456 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303457 nla_put_u32(skb,
3458 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303459 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460 goto fail;
3461
3462 nla_nest_end(skb, ap);
3463 }
3464 nla_nest_end(skb, aps);
3465
3466 if (nla_put_u8(skb,
3467 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3468 pData->moreData))
3469 goto fail;
3470 }
3471
3472 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303473 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303474 return;
3475
3476fail:
3477 kfree_skb(skb);
3478 return;
3479
3480}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303481
3482static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3483 void *pMsg)
3484{
3485 struct sk_buff *skb;
3486 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3487 tpSirWifiFullScanResultEvent pData =
3488 (tpSirWifiFullScanResultEvent) (pMsg);
3489
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303490 ENTER();
3491
3492 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303493 hddLog(LOGE,
3494 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303495 return;
3496 }
3497 if (!pMsg)
3498 {
3499 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303500 return;
3501 }
3502
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303503 /*
3504 * If the full scan result including IE data exceeds NL 4K size
3505 * limitation, drop that beacon/probe rsp frame.
3506 */
3507 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3508 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3509 return;
3510 }
3511
Dino Mycle6fb96c12014-06-10 11:52:40 +05303512 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303513#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3514 NULL,
3515#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303516 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3517 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3518 GFP_KERNEL);
3519
3520 if (!skb) {
3521 hddLog(VOS_TRACE_LEVEL_ERROR,
3522 FL("cfg80211_vendor_event_alloc failed"));
3523 return;
3524 }
3525
Dino Mycle6fb96c12014-06-10 11:52:40 +05303526 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3527 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3528 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3529 "Ssid (%s)"
3530 "Bssid (" MAC_ADDRESS_STR ")"
3531 "Channel (%u)"
3532 "Rssi (%d)"
3533 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303534 "RTT_SD (%u)"
3535 "Bcn Period %d"
3536 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303537 pData->ap.ts,
3538 pData->ap.ssid,
3539 MAC_ADDR_ARRAY(pData->ap.bssid),
3540 pData->ap.channel,
3541 pData->ap.rssi,
3542 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303543 pData->ap.rtt_sd,
3544 pData->ap.beaconPeriod,
3545 pData->ap.capability);
3546
Dino Mycle6fb96c12014-06-10 11:52:40 +05303547 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3548 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3549 pData->requestId) ||
3550 nla_put_u64(skb,
3551 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3552 pData->ap.ts) ||
3553 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3554 sizeof(pData->ap.ssid),
3555 pData->ap.ssid) ||
3556 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3557 WNI_CFG_BSSID_LEN,
3558 pData->ap.bssid) ||
3559 nla_put_u32(skb,
3560 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3561 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303562 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303563 pData->ap.rssi) ||
3564 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3565 pData->ap.rtt) ||
3566 nla_put_u32(skb,
3567 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3568 pData->ap.rtt_sd) ||
3569 nla_put_u16(skb,
3570 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3571 pData->ap.beaconPeriod) ||
3572 nla_put_u16(skb,
3573 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3574 pData->ap.capability) ||
3575 nla_put_u32(skb,
3576 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303577 pData->ieLength) ||
3578 nla_put_u8(skb,
3579 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3580 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303581 {
3582 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3583 goto nla_put_failure;
3584 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303585
3586 if (pData->ieLength) {
3587 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3588 pData->ieLength,
3589 pData->ie))
3590 {
3591 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3592 goto nla_put_failure;
3593 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303594 }
3595
3596 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303597 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303598 return;
3599
3600nla_put_failure:
3601 kfree_skb(skb);
3602 return;
3603}
3604
3605static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3606 void *pMsg)
3607{
3608 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3609 struct sk_buff *skb = NULL;
3610 tpSirEXTScanResultsAvailableIndParams pData =
3611 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3612
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303613 ENTER();
3614
3615 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303616 hddLog(LOGE,
3617 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303618 return;
3619 }
3620 if (!pMsg)
3621 {
3622 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303623 return;
3624 }
3625
3626 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303627#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3628 NULL,
3629#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303630 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3631 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3632 GFP_KERNEL);
3633
3634 if (!skb) {
3635 hddLog(VOS_TRACE_LEVEL_ERROR,
3636 FL("cfg80211_vendor_event_alloc failed"));
3637 return;
3638 }
3639
Dino Mycle6fb96c12014-06-10 11:52:40 +05303640 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3641 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3642 pData->numResultsAvailable);
3643 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3644 pData->requestId) ||
3645 nla_put_u32(skb,
3646 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3647 pData->numResultsAvailable)) {
3648 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3649 goto nla_put_failure;
3650 }
3651
3652 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303653 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303654 return;
3655
3656nla_put_failure:
3657 kfree_skb(skb);
3658 return;
3659}
3660
3661static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3662{
3663 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3664 struct sk_buff *skb = NULL;
3665 tpSirEXTScanProgressIndParams pData =
3666 (tpSirEXTScanProgressIndParams) pMsg;
3667
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303668 ENTER();
3669
3670 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303671 hddLog(LOGE,
3672 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303673 return;
3674 }
3675 if (!pMsg)
3676 {
3677 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303678 return;
3679 }
3680
3681 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303682#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3683 NULL,
3684#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303685 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3686 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3687 GFP_KERNEL);
3688
3689 if (!skb) {
3690 hddLog(VOS_TRACE_LEVEL_ERROR,
3691 FL("cfg80211_vendor_event_alloc failed"));
3692 return;
3693 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303694 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303695 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3696 pData->extScanEventType);
3697 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3698 pData->status);
3699
3700 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3701 pData->extScanEventType) ||
3702 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303703 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3704 pData->requestId) ||
3705 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303706 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3707 pData->status)) {
3708 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3709 goto nla_put_failure;
3710 }
3711
3712 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303713 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303714 return;
3715
3716nla_put_failure:
3717 kfree_skb(skb);
3718 return;
3719}
3720
3721void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3722 void *pMsg)
3723{
3724 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3725
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303726 ENTER();
3727
Dino Mycle6fb96c12014-06-10 11:52:40 +05303728 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303729 return;
3730 }
3731
3732 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3733
3734
3735 switch(evType) {
3736 case SIR_HAL_EXTSCAN_START_RSP:
3737 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3738 break;
3739
3740 case SIR_HAL_EXTSCAN_STOP_RSP:
3741 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3742 break;
3743 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3744 /* There is no need to send this response to upper layer
3745 Just log the message */
3746 hddLog(VOS_TRACE_LEVEL_INFO,
3747 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3748 break;
3749 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3750 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3751 break;
3752
3753 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3754 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3755 break;
3756
Dino Mycle6fb96c12014-06-10 11:52:40 +05303757 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303758 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303759 break;
3760 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3761 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3762 break;
3763 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3764 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3765 break;
3766 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3767 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3768 break;
3769 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3770 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3771 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303772 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3773 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3774 break;
3775 default:
3776 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3777 break;
3778 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303779 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303780}
3781
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303782static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3783 struct wireless_dev *wdev,
3784 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303785{
Dino Myclee8843b32014-07-04 14:21:45 +05303786 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303787 struct net_device *dev = wdev->netdev;
3788 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3789 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3790 struct nlattr
3791 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3792 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303793 struct hdd_ext_scan_context *context;
3794 unsigned long rc;
3795 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303796
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303797 ENTER();
3798
Dino Mycle6fb96c12014-06-10 11:52:40 +05303799 status = wlan_hdd_validate_context(pHddCtx);
3800 if (0 != status)
3801 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303802 return -EINVAL;
3803 }
Dino Myclee8843b32014-07-04 14:21:45 +05303804 /* check the EXTScan Capability */
3805 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303806 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3807 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303808 {
3809 hddLog(VOS_TRACE_LEVEL_ERROR,
3810 FL("EXTScan not enabled/supported by Firmware"));
3811 return -EINVAL;
3812 }
3813
Dino Mycle6fb96c12014-06-10 11:52:40 +05303814 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3815 data, dataLen,
3816 wlan_hdd_extscan_config_policy)) {
3817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3818 return -EINVAL;
3819 }
3820
3821 /* Parse and fetch request Id */
3822 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3823 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3824 return -EINVAL;
3825 }
3826
Dino Myclee8843b32014-07-04 14:21:45 +05303827 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303828 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303829 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303830
Dino Myclee8843b32014-07-04 14:21:45 +05303831 reqMsg.sessionId = pAdapter->sessionId;
3832 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303833
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303834 vos_spin_lock_acquire(&hdd_context_lock);
3835 context = &pHddCtx->ext_scan_context;
3836 context->request_id = reqMsg.requestId;
3837 INIT_COMPLETION(context->response_event);
3838 vos_spin_lock_release(&hdd_context_lock);
3839
Dino Myclee8843b32014-07-04 14:21:45 +05303840 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303841 if (!HAL_STATUS_SUCCESS(status)) {
3842 hddLog(VOS_TRACE_LEVEL_ERROR,
3843 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303844 return -EINVAL;
3845 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303846
3847 rc = wait_for_completion_timeout(&context->response_event,
3848 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3849 if (!rc) {
3850 hddLog(LOGE, FL("Target response timed out"));
3851 return -ETIMEDOUT;
3852 }
3853
3854 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3855 if (ret)
3856 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3857
3858 return ret;
3859
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303860 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303861 return 0;
3862}
3863
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303864static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3865 struct wireless_dev *wdev,
3866 const void *data, int dataLen)
3867{
3868 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303869
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303870 vos_ssr_protect(__func__);
3871 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3872 vos_ssr_unprotect(__func__);
3873
3874 return ret;
3875}
3876
3877static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3878 struct wireless_dev *wdev,
3879 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303880{
Dino Myclee8843b32014-07-04 14:21:45 +05303881 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303882 struct net_device *dev = wdev->netdev;
3883 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3884 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3885 struct nlattr
3886 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3887 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303888 struct hdd_ext_scan_context *context;
3889 unsigned long rc;
3890 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303891
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303892 ENTER();
3893
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303894 if (VOS_FTM_MODE == hdd_get_conparam()) {
3895 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3896 return -EINVAL;
3897 }
3898
Dino Mycle6fb96c12014-06-10 11:52:40 +05303899 status = wlan_hdd_validate_context(pHddCtx);
3900 if (0 != status)
3901 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303902 return -EINVAL;
3903 }
Dino Myclee8843b32014-07-04 14:21:45 +05303904 /* check the EXTScan Capability */
3905 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303906 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3907 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303908 {
3909 hddLog(VOS_TRACE_LEVEL_ERROR,
3910 FL("EXTScan not enabled/supported by Firmware"));
3911 return -EINVAL;
3912 }
3913
Dino Mycle6fb96c12014-06-10 11:52:40 +05303914 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3915 data, dataLen,
3916 wlan_hdd_extscan_config_policy)) {
3917 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3918 return -EINVAL;
3919 }
3920 /* Parse and fetch request Id */
3921 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3922 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3923 return -EINVAL;
3924 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303925
Dino Myclee8843b32014-07-04 14:21:45 +05303926 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303927 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3928
Dino Myclee8843b32014-07-04 14:21:45 +05303929 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303930
Dino Myclee8843b32014-07-04 14:21:45 +05303931 reqMsg.sessionId = pAdapter->sessionId;
3932 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303933
3934 /* Parse and fetch flush parameter */
3935 if (!tb
3936 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3937 {
3938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3939 goto failed;
3940 }
Dino Myclee8843b32014-07-04 14:21:45 +05303941 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303942 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3943
Dino Myclee8843b32014-07-04 14:21:45 +05303944 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303945
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303946 spin_lock(&hdd_context_lock);
3947 context = &pHddCtx->ext_scan_context;
3948 context->request_id = reqMsg.requestId;
3949 context->ignore_cached_results = false;
3950 INIT_COMPLETION(context->response_event);
3951 spin_unlock(&hdd_context_lock);
3952
Dino Myclee8843b32014-07-04 14:21:45 +05303953 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303954 if (!HAL_STATUS_SUCCESS(status)) {
3955 hddLog(VOS_TRACE_LEVEL_ERROR,
3956 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303957 return -EINVAL;
3958 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303959
3960 rc = wait_for_completion_timeout(&context->response_event,
3961 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3962 if (!rc) {
3963 hddLog(LOGE, FL("Target response timed out"));
3964 retval = -ETIMEDOUT;
3965 spin_lock(&hdd_context_lock);
3966 context->ignore_cached_results = true;
3967 spin_unlock(&hdd_context_lock);
3968 } else {
3969 spin_lock(&hdd_context_lock);
3970 retval = context->response_status;
3971 spin_unlock(&hdd_context_lock);
3972 }
3973
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303974 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303975 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303976
3977failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303978 return -EINVAL;
3979}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303980static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3981 struct wireless_dev *wdev,
3982 const void *data, int dataLen)
3983{
3984 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303985
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303986 vos_ssr_protect(__func__);
3987 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3988 vos_ssr_unprotect(__func__);
3989
3990 return ret;
3991}
3992
3993static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303994 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303995 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303996{
3997 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3998 struct net_device *dev = wdev->netdev;
3999 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4000 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4001 struct nlattr
4002 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4003 struct nlattr
4004 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4005 struct nlattr *apTh;
4006 eHalStatus status;
4007 tANI_U8 i = 0;
4008 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304009 struct hdd_ext_scan_context *context;
4010 tANI_U32 request_id;
4011 unsigned long rc;
4012 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304013
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304014 ENTER();
4015
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304016 if (VOS_FTM_MODE == hdd_get_conparam()) {
4017 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4018 return -EINVAL;
4019 }
4020
Dino Mycle6fb96c12014-06-10 11:52:40 +05304021 status = wlan_hdd_validate_context(pHddCtx);
4022 if (0 != status)
4023 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304024 return -EINVAL;
4025 }
Dino Myclee8843b32014-07-04 14:21:45 +05304026 /* check the EXTScan Capability */
4027 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304028 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4029 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304030 {
4031 hddLog(VOS_TRACE_LEVEL_ERROR,
4032 FL("EXTScan not enabled/supported by Firmware"));
4033 return -EINVAL;
4034 }
4035
Dino Mycle6fb96c12014-06-10 11:52:40 +05304036 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4037 data, dataLen,
4038 wlan_hdd_extscan_config_policy)) {
4039 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4040 return -EINVAL;
4041 }
4042
4043 /* Parse and fetch request Id */
4044 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4045 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4046 return -EINVAL;
4047 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304048 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4049 vos_mem_malloc(sizeof(*pReqMsg));
4050 if (!pReqMsg) {
4051 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4052 return -ENOMEM;
4053 }
4054
Dino Myclee8843b32014-07-04 14:21:45 +05304055
Dino Mycle6fb96c12014-06-10 11:52:40 +05304056 pReqMsg->requestId = nla_get_u32(
4057 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4058 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4059
4060 /* Parse and fetch number of APs */
4061 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4062 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4063 goto fail;
4064 }
4065
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304066 /* Parse and fetch lost ap sample size */
4067 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4068 hddLog(LOGE, FL("attr lost ap sample size failed"));
4069 goto fail;
4070 }
4071
4072 pReqMsg->lostBssidSampleSize = nla_get_u32(
4073 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4074 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4075
Dino Mycle6fb96c12014-06-10 11:52:40 +05304076 pReqMsg->sessionId = pAdapter->sessionId;
4077 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4078
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304079 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304080 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304081 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4082 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4083 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4084 goto fail;
4085 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304086 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304087
4088 nla_for_each_nested(apTh,
4089 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304090 if (i == pReqMsg->numBssid) {
4091 hddLog(LOGW, FL("Ignoring excess AP"));
4092 break;
4093 }
4094
Dino Mycle6fb96c12014-06-10 11:52:40 +05304095 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4096 nla_data(apTh), nla_len(apTh),
4097 NULL)) {
4098 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4099 goto fail;
4100 }
4101
4102 /* Parse and fetch MAC address */
4103 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4104 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4105 goto fail;
4106 }
4107 memcpy(pReqMsg->ap[i].bssid, nla_data(
4108 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4109 sizeof(tSirMacAddr));
4110 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4111
4112 /* Parse and fetch low RSSI */
4113 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4114 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4115 goto fail;
4116 }
4117 pReqMsg->ap[i].low = nla_get_s32(
4118 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4119 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4120
4121 /* Parse and fetch high RSSI */
4122 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4123 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4124 goto fail;
4125 }
4126 pReqMsg->ap[i].high = nla_get_s32(
4127 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4128 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4129 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304130 i++;
4131 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304132
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304133 if (i < pReqMsg->numBssid) {
4134 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4135 i, pReqMsg->numBssid);
4136 pReqMsg->numBssid = i;
4137 }
4138
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304139 context = &pHddCtx->ext_scan_context;
4140 spin_lock(&hdd_context_lock);
4141 INIT_COMPLETION(context->response_event);
4142 context->request_id = request_id = pReqMsg->requestId;
4143 spin_unlock(&hdd_context_lock);
4144
Dino Mycle6fb96c12014-06-10 11:52:40 +05304145 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4146 if (!HAL_STATUS_SUCCESS(status)) {
4147 hddLog(VOS_TRACE_LEVEL_ERROR,
4148 FL("sme_SetBssHotlist failed(err=%d)"), status);
4149 vos_mem_free(pReqMsg);
4150 return -EINVAL;
4151 }
4152
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304153 /* request was sent -- wait for the response */
4154 rc = wait_for_completion_timeout(&context->response_event,
4155 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4156
4157 if (!rc) {
4158 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4159 retval = -ETIMEDOUT;
4160 } else {
4161 spin_lock(&hdd_context_lock);
4162 if (context->request_id == request_id)
4163 retval = context->response_status;
4164 else
4165 retval = -EINVAL;
4166 spin_unlock(&hdd_context_lock);
4167 }
4168
Dino Myclee8843b32014-07-04 14:21:45 +05304169 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304170 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304171 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304172
4173fail:
4174 vos_mem_free(pReqMsg);
4175 return -EINVAL;
4176}
4177
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304178static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4179 struct wireless_dev *wdev,
4180 const void *data, int dataLen)
4181{
4182 int ret = 0;
4183
4184 vos_ssr_protect(__func__);
4185 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4186 dataLen);
4187 vos_ssr_unprotect(__func__);
4188
4189 return ret;
4190}
4191
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304192static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304193 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304194 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304195{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304196 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4197 struct net_device *dev = wdev->netdev;
4198 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4199 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4200 uint8_t num_channels = 0;
4201 uint8_t num_chan_new = 0;
4202 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304203 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304204 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304205 tWifiBand wifiBand;
4206 eHalStatus status;
4207 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304208 tANI_U8 i,j,k;
4209 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304210
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304211 ENTER();
4212
Dino Mycle6fb96c12014-06-10 11:52:40 +05304213 status = wlan_hdd_validate_context(pHddCtx);
4214 if (0 != status)
4215 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304216 return -EINVAL;
4217 }
Dino Myclee8843b32014-07-04 14:21:45 +05304218
Dino Mycle6fb96c12014-06-10 11:52:40 +05304219 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4220 data, dataLen,
4221 wlan_hdd_extscan_config_policy)) {
4222 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4223 return -EINVAL;
4224 }
4225
4226 /* Parse and fetch request Id */
4227 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4228 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4229 return -EINVAL;
4230 }
4231 requestId = nla_get_u32(
4232 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4233 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4234
4235 /* Parse and fetch wifi band */
4236 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4237 {
4238 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4239 return -EINVAL;
4240 }
4241 wifiBand = nla_get_u32(
4242 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4243 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4244
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304245 /* Parse and fetch max channels */
4246 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4247 {
4248 hddLog(LOGE, FL("attr max channels failed"));
4249 return -EINVAL;
4250 }
4251 maxChannels = nla_get_u32(
4252 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4253 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4254
Dino Mycle6fb96c12014-06-10 11:52:40 +05304255 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304256 wifiBand, chan_list,
4257 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304258 if (eHAL_STATUS_SUCCESS != status) {
4259 hddLog(VOS_TRACE_LEVEL_ERROR,
4260 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4261 return -EINVAL;
4262 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304263
Agrawal Ashish16abf782016-08-18 22:42:59 +05304264 num_channels = VOS_MIN(num_channels, maxChannels);
4265 num_chan_new = num_channels;
4266 /* remove the indoor only channels if iface is SAP */
4267 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4268 {
4269 num_chan_new = 0;
4270 for (i = 0; i < num_channels; i++)
4271 for (j = 0; j < IEEE80211_NUM_BANDS; j++) {
4272 if (wiphy->bands[j] == NULL)
4273 continue;
4274 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4275 if ((chan_list[i] ==
4276 wiphy->bands[j]->channels[k].center_freq) &&
4277 (!(wiphy->bands[j]->channels[k].flags &
4278 IEEE80211_CHAN_INDOOR_ONLY))) {
4279 chan_list[num_chan_new] = chan_list[i];
4280 num_chan_new++;
4281 }
4282 }
4283 }
4284 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304285
Agrawal Ashish16abf782016-08-18 22:42:59 +05304286 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4287 for (i = 0; i < num_chan_new; i++)
4288 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4289 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304290
4291 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304292 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304293 NLMSG_HDRLEN);
4294
4295 if (!replySkb) {
4296 hddLog(VOS_TRACE_LEVEL_ERROR,
4297 FL("valid channels: buffer alloc fail"));
4298 return -EINVAL;
4299 }
4300 if (nla_put_u32(replySkb,
4301 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304302 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304303 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304304 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304305
4306 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4307 kfree_skb(replySkb);
4308 return -EINVAL;
4309 }
4310
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304311 ret = cfg80211_vendor_cmd_reply(replySkb);
4312
4313 EXIT();
4314 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304315}
4316
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304317static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4318 struct wireless_dev *wdev,
4319 const void *data, int dataLen)
4320{
4321 int ret = 0;
4322
4323 vos_ssr_protect(__func__);
4324 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4325 dataLen);
4326 vos_ssr_unprotect(__func__);
4327
4328 return ret;
4329}
4330
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304331static int hdd_extscan_start_fill_bucket_channel_spec(
4332 hdd_context_t *pHddCtx,
4333 tpSirEXTScanStartReqParams pReqMsg,
4334 struct nlattr **tb)
4335{
4336 struct nlattr *bucket[
4337 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4338 struct nlattr *channel[
4339 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4340 struct nlattr *buckets;
4341 struct nlattr *channels;
4342 int rem1, rem2;
4343 eHalStatus status;
4344 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304345 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304346 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4347 tANI_U32 passive_max_chn_time, active_max_chn_time;
4348
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304349 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304350 bktIndex = 0;
4351
4352 nla_for_each_nested(buckets,
4353 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304354 if (bktIndex >= expected_buckets) {
4355 hddLog(LOGW, FL("ignoring excess buckets"));
4356 break;
4357 }
4358
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304359 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304360 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4361 nla_data(buckets), nla_len(buckets),
4362 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304363 hddLog(LOGE, FL("nla_parse failed"));
4364 return -EINVAL;
4365 }
4366
4367 /* Parse and fetch bucket spec */
4368 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4369 hddLog(LOGE, FL("attr bucket index failed"));
4370 return -EINVAL;
4371 }
4372 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4373 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4374 hddLog(LOG1, FL("Bucket spec Index %d"),
4375 pReqMsg->buckets[bktIndex].bucket);
4376
4377 /* Parse and fetch wifi band */
4378 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4379 hddLog(LOGE, FL("attr wifi band failed"));
4380 return -EINVAL;
4381 }
4382 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4383 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4384 hddLog(LOG1, FL("Wifi band %d"),
4385 pReqMsg->buckets[bktIndex].band);
4386
4387 /* Parse and fetch period */
4388 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4389 hddLog(LOGE, FL("attr period failed"));
4390 return -EINVAL;
4391 }
4392 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4393 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4394 hddLog(LOG1, FL("period %d"),
4395 pReqMsg->buckets[bktIndex].period);
4396
4397 /* Parse and fetch report events */
4398 if (!bucket[
4399 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4400 hddLog(LOGE, FL("attr report events failed"));
4401 return -EINVAL;
4402 }
4403 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4404 bucket[
4405 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4406 hddLog(LOG1, FL("report events %d"),
4407 pReqMsg->buckets[bktIndex].reportEvents);
4408
4409 /* Parse and fetch max period */
4410 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4411 hddLog(LOGE, FL("attr max period failed"));
4412 return -EINVAL;
4413 }
4414 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4415 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4416 hddLog(LOG1, FL("max period %u"),
4417 pReqMsg->buckets[bktIndex].max_period);
4418
4419 /* Parse and fetch exponent */
4420 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4421 hddLog(LOGE, FL("attr exponent failed"));
4422 return -EINVAL;
4423 }
4424 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4425 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4426 hddLog(LOG1, FL("exponent %u"),
4427 pReqMsg->buckets[bktIndex].exponent);
4428
4429 /* Parse and fetch step count */
4430 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4431 hddLog(LOGE, FL("attr step count failed"));
4432 return -EINVAL;
4433 }
4434 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4435 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4436 hddLog(LOG1, FL("Step count %u"),
4437 pReqMsg->buckets[bktIndex].step_count);
4438
4439 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4440 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4441
4442 /* Framework shall pass the channel list if the input WiFi band is
4443 * WIFI_BAND_UNSPECIFIED.
4444 * If the input WiFi band is specified (any value other than
4445 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4446 */
4447 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4448 numChannels = 0;
4449 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4450 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4451 pReqMsg->buckets[bktIndex].band,
4452 chanList, &numChannels);
4453 if (!HAL_STATUS_SUCCESS(status)) {
4454 hddLog(LOGE,
4455 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4456 status);
4457 return -EINVAL;
4458 }
4459
4460 pReqMsg->buckets[bktIndex].numChannels =
4461 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4462 hddLog(LOG1, FL("Num channels %d"),
4463 pReqMsg->buckets[bktIndex].numChannels);
4464
4465 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4466 j++) {
4467 pReqMsg->buckets[bktIndex].channels[j].channel =
4468 chanList[j];
4469 pReqMsg->buckets[bktIndex].channels[j].
4470 chnlClass = 0;
4471 if (CSR_IS_CHANNEL_DFS(
4472 vos_freq_to_chan(chanList[j]))) {
4473 pReqMsg->buckets[bktIndex].channels[j].
4474 passive = 1;
4475 pReqMsg->buckets[bktIndex].channels[j].
4476 dwellTimeMs = passive_max_chn_time;
4477 } else {
4478 pReqMsg->buckets[bktIndex].channels[j].
4479 passive = 0;
4480 pReqMsg->buckets[bktIndex].channels[j].
4481 dwellTimeMs = active_max_chn_time;
4482 }
4483
4484 hddLog(LOG1,
4485 "Channel %u Passive %u Dwell time %u ms",
4486 pReqMsg->buckets[bktIndex].channels[j].channel,
4487 pReqMsg->buckets[bktIndex].channels[j].passive,
4488 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4489 }
4490
4491 bktIndex++;
4492 continue;
4493 }
4494
4495 /* Parse and fetch number of channels */
4496 if (!bucket[
4497 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4498 hddLog(LOGE, FL("attr num channels failed"));
4499 return -EINVAL;
4500 }
4501
4502 pReqMsg->buckets[bktIndex].numChannels =
4503 nla_get_u32(bucket[
4504 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4505 hddLog(LOG1, FL("num channels %d"),
4506 pReqMsg->buckets[bktIndex].numChannels);
4507
4508 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4509 hddLog(LOGE, FL("attr channel spec failed"));
4510 return -EINVAL;
4511 }
4512
4513 j = 0;
4514 nla_for_each_nested(channels,
4515 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4516 if (nla_parse(channel,
4517 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4518 nla_data(channels), nla_len(channels),
4519 wlan_hdd_extscan_config_policy)) {
4520 hddLog(LOGE, FL("nla_parse failed"));
4521 return -EINVAL;
4522 }
4523
4524 /* Parse and fetch channel */
4525 if (!channel[
4526 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4527 hddLog(LOGE, FL("attr channel failed"));
4528 return -EINVAL;
4529 }
4530 pReqMsg->buckets[bktIndex].channels[j].channel =
4531 nla_get_u32(channel[
4532 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4533 hddLog(LOG1, FL("channel %u"),
4534 pReqMsg->buckets[bktIndex].channels[j].channel);
4535
4536 /* Parse and fetch dwell time */
4537 if (!channel[
4538 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4539 hddLog(LOGE, FL("attr dwelltime failed"));
4540 return -EINVAL;
4541 }
4542 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4543 nla_get_u32(channel[
4544 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4545
4546 hddLog(LOG1, FL("Dwell time (%u ms)"),
4547 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4548
4549
4550 /* Parse and fetch channel spec passive */
4551 if (!channel[
4552 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4553 hddLog(LOGE,
4554 FL("attr channel spec passive failed"));
4555 return -EINVAL;
4556 }
4557 pReqMsg->buckets[bktIndex].channels[j].passive =
4558 nla_get_u8(channel[
4559 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4560 hddLog(LOG1, FL("Chnl spec passive %u"),
4561 pReqMsg->buckets[bktIndex].channels[j].passive);
4562
4563 j++;
4564 }
4565
4566 bktIndex++;
4567 }
4568
4569 return 0;
4570}
4571
4572
4573/*
4574 * define short names for the global vendor params
4575 * used by wlan_hdd_cfg80211_extscan_start()
4576 */
4577#define PARAM_MAX \
4578QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4579#define PARAM_REQUEST_ID \
4580QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4581#define PARAM_BASE_PERIOD \
4582QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4583#define PARAM_MAX_AP_PER_SCAN \
4584QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4585#define PARAM_RPT_THRHLD_PERCENT \
4586QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4587#define PARAM_RPT_THRHLD_NUM_SCANS \
4588QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4589#define PARAM_NUM_BUCKETS \
4590QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4591
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304592static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304593 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304594 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304595{
Dino Myclee8843b32014-07-04 14:21:45 +05304596 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304597 struct net_device *dev = wdev->netdev;
4598 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4599 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4600 struct nlattr *tb[PARAM_MAX + 1];
4601 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304602 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304603 tANI_U32 request_id;
4604 struct hdd_ext_scan_context *context;
4605 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304606
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304607 ENTER();
4608
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304609 if (VOS_FTM_MODE == hdd_get_conparam()) {
4610 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4611 return -EINVAL;
4612 }
4613
Dino Mycle6fb96c12014-06-10 11:52:40 +05304614 status = wlan_hdd_validate_context(pHddCtx);
4615 if (0 != status)
4616 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304617 return -EINVAL;
4618 }
Dino Myclee8843b32014-07-04 14:21:45 +05304619 /* check the EXTScan Capability */
4620 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304621 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4622 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304623 {
4624 hddLog(VOS_TRACE_LEVEL_ERROR,
4625 FL("EXTScan not enabled/supported by Firmware"));
4626 return -EINVAL;
4627 }
4628
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304629 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304630 data, dataLen,
4631 wlan_hdd_extscan_config_policy)) {
4632 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4633 return -EINVAL;
4634 }
4635
4636 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304637 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304638 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4639 return -EINVAL;
4640 }
4641
Dino Myclee8843b32014-07-04 14:21:45 +05304642 pReqMsg = (tpSirEXTScanStartReqParams)
4643 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304644 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304645 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4646 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304647 }
4648
4649 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304650 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304651 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4652
4653 pReqMsg->sessionId = pAdapter->sessionId;
4654 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4655
4656 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304657 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304658 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4659 goto fail;
4660 }
4661 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304662 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304663 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4664 pReqMsg->basePeriod);
4665
4666 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304667 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304668 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4669 goto fail;
4670 }
4671 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304672 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304673 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4674 pReqMsg->maxAPperScan);
4675
4676 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304677 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304678 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4679 goto fail;
4680 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304681 pReqMsg->reportThresholdPercent = nla_get_u8(
4682 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304683 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304684 pReqMsg->reportThresholdPercent);
4685
4686 /* Parse and fetch report threshold num scans */
4687 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4688 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4689 goto fail;
4690 }
4691 pReqMsg->reportThresholdNumScans = nla_get_u8(
4692 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4693 hddLog(LOG1, FL("Report Threshold num scans %d"),
4694 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304695
4696 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304697 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304698 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4699 goto fail;
4700 }
4701 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304702 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304703 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4704 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4705 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4706 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4707 }
4708 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4709 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304710
Dino Mycle6fb96c12014-06-10 11:52:40 +05304711 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4712 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4713 goto fail;
4714 }
4715
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304716 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304717
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304718 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4719 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304720
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304721 context = &pHddCtx->ext_scan_context;
4722 spin_lock(&hdd_context_lock);
4723 INIT_COMPLETION(context->response_event);
4724 context->request_id = request_id = pReqMsg->requestId;
4725 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304726
Dino Mycle6fb96c12014-06-10 11:52:40 +05304727 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4728 if (!HAL_STATUS_SUCCESS(status)) {
4729 hddLog(VOS_TRACE_LEVEL_ERROR,
4730 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304731 goto fail;
4732 }
4733
Srinivas Dasari91727c12016-03-23 17:59:06 +05304734 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
4735
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304736 /* request was sent -- wait for the response */
4737 rc = wait_for_completion_timeout(&context->response_event,
4738 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4739
4740 if (!rc) {
4741 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4742 retval = -ETIMEDOUT;
4743 } else {
4744 spin_lock(&hdd_context_lock);
4745 if (context->request_id == request_id)
4746 retval = context->response_status;
4747 else
4748 retval = -EINVAL;
4749 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304750 }
4751
Dino Myclee8843b32014-07-04 14:21:45 +05304752 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304753 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304754 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304755
4756fail:
4757 vos_mem_free(pReqMsg);
4758 return -EINVAL;
4759}
4760
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304761/*
4762 * done with short names for the global vendor params
4763 * used by wlan_hdd_cfg80211_extscan_start()
4764 */
4765#undef PARAM_MAX
4766#undef PARAM_REQUEST_ID
4767#undef PARAM_BASE_PERIOD
4768#undef PARAMS_MAX_AP_PER_SCAN
4769#undef PARAMS_RPT_THRHLD_PERCENT
4770#undef PARAMS_RPT_THRHLD_NUM_SCANS
4771#undef PARAMS_NUM_BUCKETS
4772
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304773static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4774 struct wireless_dev *wdev,
4775 const void *data, int dataLen)
4776{
4777 int ret = 0;
4778
4779 vos_ssr_protect(__func__);
4780 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4781 vos_ssr_unprotect(__func__);
4782
4783 return ret;
4784}
4785
4786static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304787 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304788 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304789{
Dino Myclee8843b32014-07-04 14:21:45 +05304790 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304791 struct net_device *dev = wdev->netdev;
4792 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4793 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4794 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4795 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304796 int retval;
4797 unsigned long rc;
4798 struct hdd_ext_scan_context *context;
4799 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304800
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304801 ENTER();
4802
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304803 if (VOS_FTM_MODE == hdd_get_conparam()) {
4804 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4805 return -EINVAL;
4806 }
4807
Dino Mycle6fb96c12014-06-10 11:52:40 +05304808 status = wlan_hdd_validate_context(pHddCtx);
4809 if (0 != status)
4810 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304811 return -EINVAL;
4812 }
Dino Myclee8843b32014-07-04 14:21:45 +05304813 /* check the EXTScan Capability */
4814 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304815 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4816 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304817 {
4818 hddLog(VOS_TRACE_LEVEL_ERROR,
4819 FL("EXTScan not enabled/supported by Firmware"));
4820 return -EINVAL;
4821 }
4822
Dino Mycle6fb96c12014-06-10 11:52:40 +05304823 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4824 data, dataLen,
4825 wlan_hdd_extscan_config_policy)) {
4826 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4827 return -EINVAL;
4828 }
4829
4830 /* Parse and fetch request Id */
4831 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4832 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4833 return -EINVAL;
4834 }
4835
Dino Myclee8843b32014-07-04 14:21:45 +05304836 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304837 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304838 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304839
Dino Myclee8843b32014-07-04 14:21:45 +05304840 reqMsg.sessionId = pAdapter->sessionId;
4841 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304842
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304843 context = &pHddCtx->ext_scan_context;
4844 spin_lock(&hdd_context_lock);
4845 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05304846 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304847 spin_unlock(&hdd_context_lock);
4848
Dino Myclee8843b32014-07-04 14:21:45 +05304849 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304850 if (!HAL_STATUS_SUCCESS(status)) {
4851 hddLog(VOS_TRACE_LEVEL_ERROR,
4852 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304853 return -EINVAL;
4854 }
4855
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304856 /* request was sent -- wait for the response */
4857 rc = wait_for_completion_timeout(&context->response_event,
4858 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4859
4860 if (!rc) {
4861 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4862 retval = -ETIMEDOUT;
4863 } else {
4864 spin_lock(&hdd_context_lock);
4865 if (context->request_id == request_id)
4866 retval = context->response_status;
4867 else
4868 retval = -EINVAL;
4869 spin_unlock(&hdd_context_lock);
4870 }
4871
4872 return retval;
4873
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304874 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304875 return 0;
4876}
4877
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304878static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4879 struct wireless_dev *wdev,
4880 const void *data, int dataLen)
4881{
4882 int ret = 0;
4883
4884 vos_ssr_protect(__func__);
4885 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4886 vos_ssr_unprotect(__func__);
4887
4888 return ret;
4889}
4890
4891static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304892 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304893 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304894{
Dino Myclee8843b32014-07-04 14:21:45 +05304895 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304896 struct net_device *dev = wdev->netdev;
4897 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4898 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4899 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4900 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304901 struct hdd_ext_scan_context *context;
4902 tANI_U32 request_id;
4903 unsigned long rc;
4904 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304905
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304906 ENTER();
4907
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304908 if (VOS_FTM_MODE == hdd_get_conparam()) {
4909 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4910 return -EINVAL;
4911 }
4912
Dino Mycle6fb96c12014-06-10 11:52:40 +05304913 status = wlan_hdd_validate_context(pHddCtx);
4914 if (0 != status)
4915 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304916 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304917 return -EINVAL;
4918 }
Dino Myclee8843b32014-07-04 14:21:45 +05304919 /* check the EXTScan Capability */
4920 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304921 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4922 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304923 {
4924 hddLog(VOS_TRACE_LEVEL_ERROR,
4925 FL("EXTScan not enabled/supported by Firmware"));
4926 return -EINVAL;
4927 }
4928
Dino Mycle6fb96c12014-06-10 11:52:40 +05304929 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4930 data, dataLen,
4931 wlan_hdd_extscan_config_policy)) {
4932 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4933 return -EINVAL;
4934 }
4935
4936 /* Parse and fetch request Id */
4937 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4939 return -EINVAL;
4940 }
4941
Dino Myclee8843b32014-07-04 14:21:45 +05304942 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304943 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304944 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304945
Dino Myclee8843b32014-07-04 14:21:45 +05304946 reqMsg.sessionId = pAdapter->sessionId;
4947 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304948
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304949 context = &pHddCtx->ext_scan_context;
4950 spin_lock(&hdd_context_lock);
4951 INIT_COMPLETION(context->response_event);
4952 context->request_id = request_id = reqMsg.requestId;
4953 spin_unlock(&hdd_context_lock);
4954
Dino Myclee8843b32014-07-04 14:21:45 +05304955 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304956 if (!HAL_STATUS_SUCCESS(status)) {
4957 hddLog(VOS_TRACE_LEVEL_ERROR,
4958 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304959 return -EINVAL;
4960 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304961
4962 /* request was sent -- wait for the response */
4963 rc = wait_for_completion_timeout(&context->response_event,
4964 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4965 if (!rc) {
4966 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4967 retval = -ETIMEDOUT;
4968 } else {
4969 spin_lock(&hdd_context_lock);
4970 if (context->request_id == request_id)
4971 retval = context->response_status;
4972 else
4973 retval = -EINVAL;
4974 spin_unlock(&hdd_context_lock);
4975 }
4976
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304977 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304978 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304979}
4980
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304981static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4982 struct wireless_dev *wdev,
4983 const void *data, int dataLen)
4984{
4985 int ret = 0;
4986
4987 vos_ssr_protect(__func__);
4988 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4989 vos_ssr_unprotect(__func__);
4990
4991 return ret;
4992}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304993#endif /* WLAN_FEATURE_EXTSCAN */
4994
Atul Mittal115287b2014-07-08 13:26:33 +05304995/*EXT TDLS*/
4996static const struct nla_policy
4997wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4998{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05304999 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5000 .type = NLA_UNSPEC,
5001 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305002 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5003 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5004 {.type = NLA_S32 },
5005 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5006 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5007
5008};
5009
5010static const struct nla_policy
5011wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5012{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305013 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5014 .type = NLA_UNSPEC,
5015 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305016
5017};
5018
5019static const struct nla_policy
5020wlan_hdd_tdls_config_state_change_policy[
5021 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5022{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305023 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5024 .type = NLA_UNSPEC,
5025 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305026 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5027 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305028 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5029 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5030 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305031
5032};
5033
5034static const struct nla_policy
5035wlan_hdd_tdls_config_get_status_policy[
5036 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5037{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305038 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5039 .type = NLA_UNSPEC,
5040 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305041 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5042 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305043 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5044 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5045 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305046
5047};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305048
5049static const struct nla_policy
5050wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5051{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305052 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5053 .type = NLA_UNSPEC,
5054 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305055};
5056
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305057static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305058 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305059 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305060 int data_len)
5061{
5062
5063 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5064 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5065
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305066 ENTER();
5067
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305068 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305069 return -EINVAL;
5070 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305071 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305072 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305073 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305074 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305075 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305076 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305077 return -ENOTSUPP;
5078 }
5079
5080 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5081 data, data_len, wlan_hdd_mac_config)) {
5082 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5083 return -EINVAL;
5084 }
5085
5086 /* Parse and fetch mac address */
5087 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5088 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5089 return -EINVAL;
5090 }
5091
5092 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5093 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5094 VOS_MAC_ADDR_LAST_3_BYTES);
5095
Siddharth Bhal76972212014-10-15 16:22:51 +05305096 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5097
5098 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305099 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5100 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305101 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5102 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5103 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5104 {
5105 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5106 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5107 VOS_MAC_ADDRESS_LEN);
5108 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305109 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305110
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305111 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5112 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305113
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305114 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305115 return 0;
5116}
5117
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305118static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5119 struct wireless_dev *wdev,
5120 const void *data,
5121 int data_len)
5122{
5123 int ret = 0;
5124
5125 vos_ssr_protect(__func__);
5126 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5127 vos_ssr_unprotect(__func__);
5128
5129 return ret;
5130}
5131
5132static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305133 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305134 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305135 int data_len)
5136{
5137 u8 peer[6] = {0};
5138 struct net_device *dev = wdev->netdev;
5139 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5140 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5141 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5142 eHalStatus ret;
5143 tANI_S32 state;
5144 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305145 tANI_S32 global_operating_class = 0;
5146 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305147 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305148 int retVal;
5149
5150 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305151
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305152 if (!pAdapter) {
5153 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5154 return -EINVAL;
5155 }
5156
Atul Mittal115287b2014-07-08 13:26:33 +05305157 ret = wlan_hdd_validate_context(pHddCtx);
5158 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305159 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305160 return -EINVAL;
5161 }
5162 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305163 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305164 return -ENOTSUPP;
5165 }
5166 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5167 data, data_len,
5168 wlan_hdd_tdls_config_get_status_policy)) {
5169 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5170 return -EINVAL;
5171 }
5172
5173 /* Parse and fetch mac address */
5174 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5175 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5176 return -EINVAL;
5177 }
5178
5179 memcpy(peer, nla_data(
5180 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5181 sizeof(peer));
5182 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5183
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305184 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305185
Atul Mittal115287b2014-07-08 13:26:33 +05305186 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305187 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305188 NLMSG_HDRLEN);
5189
5190 if (!skb) {
5191 hddLog(VOS_TRACE_LEVEL_ERROR,
5192 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5193 return -EINVAL;
5194 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305195 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 +05305196 reason,
5197 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305198 global_operating_class,
5199 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305200 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305201 if (nla_put_s32(skb,
5202 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5203 state) ||
5204 nla_put_s32(skb,
5205 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5206 reason) ||
5207 nla_put_s32(skb,
5208 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5209 global_operating_class) ||
5210 nla_put_s32(skb,
5211 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5212 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305213
5214 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5215 goto nla_put_failure;
5216 }
5217
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305218 retVal = cfg80211_vendor_cmd_reply(skb);
5219 EXIT();
5220 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305221
5222nla_put_failure:
5223 kfree_skb(skb);
5224 return -EINVAL;
5225}
5226
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305227static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5228 struct wireless_dev *wdev,
5229 const void *data,
5230 int data_len)
5231{
5232 int ret = 0;
5233
5234 vos_ssr_protect(__func__);
5235 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5236 vos_ssr_unprotect(__func__);
5237
5238 return ret;
5239}
5240
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305241static int wlan_hdd_cfg80211_exttdls_callback(
5242#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5243 const tANI_U8* mac,
5244#else
5245 tANI_U8* mac,
5246#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305247 tANI_S32 state,
5248 tANI_S32 reason,
5249 void *ctx)
5250{
5251 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305252 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305253 tANI_S32 global_operating_class = 0;
5254 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305255 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305256
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305257 ENTER();
5258
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305259 if (!pAdapter) {
5260 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5261 return -EINVAL;
5262 }
5263
5264 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305265 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305266 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305267 return -EINVAL;
5268 }
5269
5270 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305272 return -ENOTSUPP;
5273 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305274 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5275#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5276 NULL,
5277#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305278 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5279 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5280 GFP_KERNEL);
5281
5282 if (!skb) {
5283 hddLog(VOS_TRACE_LEVEL_ERROR,
5284 FL("cfg80211_vendor_event_alloc failed"));
5285 return -EINVAL;
5286 }
5287 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305288 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5289 reason,
5290 state,
5291 global_operating_class,
5292 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305293 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5294 MAC_ADDR_ARRAY(mac));
5295
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305296 if (nla_put(skb,
5297 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5298 VOS_MAC_ADDR_SIZE, mac) ||
5299 nla_put_s32(skb,
5300 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5301 state) ||
5302 nla_put_s32(skb,
5303 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5304 reason) ||
5305 nla_put_s32(skb,
5306 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5307 channel) ||
5308 nla_put_s32(skb,
5309 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5310 global_operating_class)
5311 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305312 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5313 goto nla_put_failure;
5314 }
5315
5316 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305317 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305318 return (0);
5319
5320nla_put_failure:
5321 kfree_skb(skb);
5322 return -EINVAL;
5323}
5324
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305325static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305326 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305327 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305328 int data_len)
5329{
5330 u8 peer[6] = {0};
5331 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305332 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5333 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5334 eHalStatus status;
5335 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305336 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305337 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305338
5339 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305340
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305341 if (!dev) {
5342 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5343 return -EINVAL;
5344 }
5345
5346 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5347 if (!pAdapter) {
5348 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5349 return -EINVAL;
5350 }
5351
Atul Mittal115287b2014-07-08 13:26:33 +05305352 status = wlan_hdd_validate_context(pHddCtx);
5353 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305354 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305355 return -EINVAL;
5356 }
5357 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305358 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305359 return -ENOTSUPP;
5360 }
5361 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5362 data, data_len,
5363 wlan_hdd_tdls_config_enable_policy)) {
5364 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5365 return -EINVAL;
5366 }
5367
5368 /* Parse and fetch mac address */
5369 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5370 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5371 return -EINVAL;
5372 }
5373
5374 memcpy(peer, nla_data(
5375 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5376 sizeof(peer));
5377 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5378
5379 /* Parse and fetch channel */
5380 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5381 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5382 return -EINVAL;
5383 }
5384 pReqMsg.channel = nla_get_s32(
5385 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5386 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5387
5388 /* Parse and fetch global operating class */
5389 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5390 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5391 return -EINVAL;
5392 }
5393 pReqMsg.global_operating_class = nla_get_s32(
5394 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5395 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5396 pReqMsg.global_operating_class);
5397
5398 /* Parse and fetch latency ms */
5399 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5400 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5401 return -EINVAL;
5402 }
5403 pReqMsg.max_latency_ms = nla_get_s32(
5404 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5405 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5406 pReqMsg.max_latency_ms);
5407
5408 /* Parse and fetch required bandwidth kbps */
5409 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5410 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5411 return -EINVAL;
5412 }
5413
5414 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5415 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5416 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5417 pReqMsg.min_bandwidth_kbps);
5418
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305419 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305420 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305421 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305422 wlan_hdd_cfg80211_exttdls_callback);
5423
5424 EXIT();
5425 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305426}
5427
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305428static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5429 struct wireless_dev *wdev,
5430 const void *data,
5431 int data_len)
5432{
5433 int ret = 0;
5434
5435 vos_ssr_protect(__func__);
5436 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5437 vos_ssr_unprotect(__func__);
5438
5439 return ret;
5440}
5441
5442static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305443 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305444 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305445 int data_len)
5446{
5447 u8 peer[6] = {0};
5448 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305449 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5450 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5451 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305452 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305453 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305454
5455 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305456
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305457 if (!dev) {
5458 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5459 return -EINVAL;
5460 }
5461
5462 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5463 if (!pAdapter) {
5464 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5465 return -EINVAL;
5466 }
5467
Atul Mittal115287b2014-07-08 13:26:33 +05305468 status = wlan_hdd_validate_context(pHddCtx);
5469 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305470 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305471 return -EINVAL;
5472 }
5473 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305474 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305475 return -ENOTSUPP;
5476 }
5477 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5478 data, data_len,
5479 wlan_hdd_tdls_config_disable_policy)) {
5480 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5481 return -EINVAL;
5482 }
5483 /* Parse and fetch mac address */
5484 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5485 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5486 return -EINVAL;
5487 }
5488
5489 memcpy(peer, nla_data(
5490 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5491 sizeof(peer));
5492 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5493
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305494 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5495
5496 EXIT();
5497 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305498}
5499
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305500static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5501 struct wireless_dev *wdev,
5502 const void *data,
5503 int data_len)
5504{
5505 int ret = 0;
5506
5507 vos_ssr_protect(__func__);
5508 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5509 vos_ssr_unprotect(__func__);
5510
5511 return ret;
5512}
5513
Dasari Srinivas7875a302014-09-26 17:50:57 +05305514static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305515__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305516 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305517 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305518{
5519 struct net_device *dev = wdev->netdev;
5520 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5521 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5522 struct sk_buff *skb = NULL;
5523 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305524 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305525
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305526 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305527
5528 ret = wlan_hdd_validate_context(pHddCtx);
5529 if (0 != ret)
5530 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305531 return ret;
5532 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305533 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5534 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5535 fset |= WIFI_FEATURE_INFRA;
5536 }
5537
5538 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5539 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5540 fset |= WIFI_FEATURE_INFRA_5G;
5541 }
5542
5543#ifdef WLAN_FEATURE_P2P
5544 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5545 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5546 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5547 fset |= WIFI_FEATURE_P2P;
5548 }
5549#endif
5550
5551 /* Soft-AP is supported currently by default */
5552 fset |= WIFI_FEATURE_SOFT_AP;
5553
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305554 /* HOTSPOT is a supplicant feature, enable it by default */
5555 fset |= WIFI_FEATURE_HOTSPOT;
5556
Dasari Srinivas7875a302014-09-26 17:50:57 +05305557#ifdef WLAN_FEATURE_EXTSCAN
5558 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305559 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5560 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5561 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305562 fset |= WIFI_FEATURE_EXTSCAN;
5563 }
5564#endif
5565
Dasari Srinivas7875a302014-09-26 17:50:57 +05305566 if (sme_IsFeatureSupportedByFW(NAN)) {
5567 hddLog(LOG1, FL("NAN is supported by firmware"));
5568 fset |= WIFI_FEATURE_NAN;
5569 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305570
5571 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05305572 if (sme_IsFeatureSupportedByFW(RTT) &&
5573 pHddCtx->cfg_ini->enable_rtt_support) {
5574 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305575 fset |= WIFI_FEATURE_D2AP_RTT;
5576 }
5577
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305578 if (sme_IsFeatureSupportedByFW(RTT3)) {
5579 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5580 fset |= WIFI_FEATURE_RTT3;
5581 }
5582
Dasari Srinivas7875a302014-09-26 17:50:57 +05305583#ifdef FEATURE_WLAN_BATCH_SCAN
5584 if (fset & WIFI_FEATURE_EXTSCAN) {
5585 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5586 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5587 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5588 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5589 fset |= WIFI_FEATURE_BATCH_SCAN;
5590 }
5591#endif
5592
5593#ifdef FEATURE_WLAN_SCAN_PNO
5594 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5595 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5596 hddLog(LOG1, FL("PNO is supported by firmware"));
5597 fset |= WIFI_FEATURE_PNO;
5598 }
5599#endif
5600
5601 /* STA+STA is supported currently by default */
5602 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5603
5604#ifdef FEATURE_WLAN_TDLS
5605 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5606 sme_IsFeatureSupportedByFW(TDLS)) {
5607 hddLog(LOG1, FL("TDLS is supported by firmware"));
5608 fset |= WIFI_FEATURE_TDLS;
5609 }
5610
5611 /* TDLS_OFFCHANNEL is not supported currently by default */
5612#endif
5613
5614#ifdef WLAN_AP_STA_CONCURRENCY
5615 /* AP+STA concurrency is supported currently by default */
5616 fset |= WIFI_FEATURE_AP_STA;
5617#endif
5618
Mukul Sharma5add0532015-08-17 15:57:47 +05305619#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05305620 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
5621 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05305622 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5623 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05305624 }
Mukul Sharma5add0532015-08-17 15:57:47 +05305625#endif
5626
Dasari Srinivas7875a302014-09-26 17:50:57 +05305627 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5628 NLMSG_HDRLEN);
5629
5630 if (!skb) {
5631 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5632 return -EINVAL;
5633 }
5634 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5635
5636 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5637 hddLog(LOGE, FL("nla put fail"));
5638 goto nla_put_failure;
5639 }
5640
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305641 ret = cfg80211_vendor_cmd_reply(skb);
5642 EXIT();
5643 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305644
5645nla_put_failure:
5646 kfree_skb(skb);
5647 return -EINVAL;
5648}
5649
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305650static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305651wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5652 struct wireless_dev *wdev,
5653 const void *data, int data_len)
5654{
5655 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305656 vos_ssr_protect(__func__);
5657 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5658 vos_ssr_unprotect(__func__);
5659
5660 return ret;
5661}
5662
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305663
5664static const struct
5665nla_policy
5666qca_wlan_vendor_wifi_logger_get_ring_data_policy
5667[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5668 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5669 = {.type = NLA_U32 },
5670};
5671
5672static int
5673 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5674 struct wireless_dev *wdev,
5675 const void *data,
5676 int data_len)
5677{
5678 int ret;
5679 VOS_STATUS status;
5680 uint32_t ring_id;
5681 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5682 struct nlattr *tb
5683 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5684
5685 ENTER();
5686
5687 ret = wlan_hdd_validate_context(hdd_ctx);
5688 if (0 != ret) {
5689 return ret;
5690 }
5691
5692 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5693 data, data_len,
5694 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5695 hddLog(LOGE, FL("Invalid attribute"));
5696 return -EINVAL;
5697 }
5698
5699 /* Parse and fetch ring id */
5700 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5701 hddLog(LOGE, FL("attr ATTR failed"));
5702 return -EINVAL;
5703 }
5704
5705 ring_id = nla_get_u32(
5706 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5707
5708 hddLog(LOG1, FL("Bug report triggered by framework"));
5709
5710 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5711 WLAN_LOG_INDICATOR_FRAMEWORK,
5712 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305713 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305714 );
5715 if (VOS_STATUS_SUCCESS != status) {
5716 hddLog(LOGE, FL("Failed to trigger bug report"));
5717
5718 return -EINVAL;
5719 }
5720
5721 return 0;
5722
5723
5724}
5725
5726
5727static int
5728 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5729 struct wireless_dev *wdev,
5730 const void *data,
5731 int data_len)
5732{
5733 int ret = 0;
5734
5735 vos_ssr_protect(__func__);
5736 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5737 wdev, data, data_len);
5738 vos_ssr_unprotect(__func__);
5739
5740 return ret;
5741
5742}
5743
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305744#define MAX_CONCURRENT_MATRIX \
5745 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
5746#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
5747 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
5748static const struct nla_policy
5749wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
5750 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
5751};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305752
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;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305760 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305761 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
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305773 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
5774 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305775 hddLog(LOGE, FL("Invalid ATTR"));
5776 return -EINVAL;
5777 }
5778
5779 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305780 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305781 hddLog(LOGE, FL("Attr max feature set size failed"));
5782 return -EINVAL;
5783 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305784 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305785 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5786
5787 /* Fill feature combination matrix */
5788 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305789 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5790 WIFI_FEATURE_P2P;
5791
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305792 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5793 WIFI_FEATURE_SOFT_AP;
5794
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305795 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5796 WIFI_FEATURE_SOFT_AP;
5797
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305798 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5799 WIFI_FEATURE_SOFT_AP |
5800 WIFI_FEATURE_P2P;
5801
5802 /* Add more feature combinations here */
5803
5804 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5805 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5806 hddLog(LOG1, "Feature set matrix");
5807 for (i = 0; i < feature_sets; i++)
5808 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5809
5810 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5811 sizeof(u32) * feature_sets +
5812 NLMSG_HDRLEN);
5813
5814 if (reply_skb) {
5815 if (nla_put_u32(reply_skb,
5816 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5817 feature_sets) ||
5818 nla_put(reply_skb,
5819 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5820 sizeof(u32) * feature_sets, feature_set_matrix)) {
5821 hddLog(LOGE, FL("nla put fail"));
5822 kfree_skb(reply_skb);
5823 return -EINVAL;
5824 }
5825
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305826 ret = cfg80211_vendor_cmd_reply(reply_skb);
5827 EXIT();
5828 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305829 }
5830 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5831 return -ENOMEM;
5832
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305833}
5834
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305835#undef MAX_CONCURRENT_MATRIX
5836#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
5837
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305838static int
5839wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5840 struct wireless_dev *wdev,
5841 const void *data, int data_len)
5842{
5843 int ret = 0;
5844
5845 vos_ssr_protect(__func__);
5846 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5847 data_len);
5848 vos_ssr_unprotect(__func__);
5849
5850 return ret;
5851}
5852
c_manjeecfd1efb2015-09-25 19:32:34 +05305853
5854static int
5855__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5856 struct wireless_dev *wdev,
5857 const void *data, int data_len)
5858{
5859 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5860 int ret;
5861 ENTER();
5862
5863 ret = wlan_hdd_validate_context(pHddCtx);
5864 if (0 != ret)
5865 {
5866 return ret;
5867 }
5868
5869 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5870 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5871 {
5872 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05305873 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05305874 }
5875 /*call common API for FW mem dump req*/
5876 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5877
Abhishek Singhc783fa72015-12-09 18:07:34 +05305878 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305879 {
5880 /*indicate to userspace the status of fw mem dump */
5881 wlan_indicate_mem_dump_complete(true);
5882 }
5883 else
5884 {
5885 /*else send failure to userspace */
5886 wlan_indicate_mem_dump_complete(false);
5887 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305888 EXIT();
5889 return ret;
5890}
5891
5892/**
5893 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5894 * @wiphy: pointer to wireless wiphy structure.
5895 * @wdev: pointer to wireless_dev structure.
5896 * @data: Pointer to the NL data.
5897 * @data_len:Length of @data
5898 *
5899 * This is called when wlan driver needs to get the firmware memory dump
5900 * via vendor specific command.
5901 *
5902 * Return: 0 on success, error number otherwise.
5903 */
5904
5905static int
5906wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5907 struct wireless_dev *wdev,
5908 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305909{
5910 int ret = 0;
5911 vos_ssr_protect(__func__);
5912 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5913 data_len);
5914 vos_ssr_unprotect(__func__);
5915 return ret;
5916}
c_manjeecfd1efb2015-09-25 19:32:34 +05305917
Sushant Kaushik8e644982015-09-23 12:18:54 +05305918static const struct
5919nla_policy
5920qca_wlan_vendor_wifi_logger_start_policy
5921[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5922 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5923 = {.type = NLA_U32 },
5924 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5925 = {.type = NLA_U32 },
5926 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5927 = {.type = NLA_U32 },
5928};
5929
5930/**
5931 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5932 * or disable the collection of packet statistics from the firmware
5933 * @wiphy: WIPHY structure pointer
5934 * @wdev: Wireless device structure pointer
5935 * @data: Pointer to the data received
5936 * @data_len: Length of the data received
5937 *
5938 * This function is used to enable or disable the collection of packet
5939 * statistics from the firmware
5940 *
5941 * Return: 0 on success and errno on failure
5942 */
5943static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5944 struct wireless_dev *wdev,
5945 const void *data,
5946 int data_len)
5947{
5948 eHalStatus status;
5949 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5950 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5951 tAniWifiStartLog start_log;
5952
5953 status = wlan_hdd_validate_context(hdd_ctx);
5954 if (0 != status) {
5955 return -EINVAL;
5956 }
5957
5958 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5959 data, data_len,
5960 qca_wlan_vendor_wifi_logger_start_policy)) {
5961 hddLog(LOGE, FL("Invalid attribute"));
5962 return -EINVAL;
5963 }
5964
5965 /* Parse and fetch ring id */
5966 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5967 hddLog(LOGE, FL("attr ATTR failed"));
5968 return -EINVAL;
5969 }
5970 start_log.ringId = nla_get_u32(
5971 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5972 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5973
5974 /* Parse and fetch verbose level */
5975 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5976 hddLog(LOGE, FL("attr verbose_level failed"));
5977 return -EINVAL;
5978 }
5979 start_log.verboseLevel = nla_get_u32(
5980 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5981 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5982
5983 /* Parse and fetch flag */
5984 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5985 hddLog(LOGE, FL("attr flag failed"));
5986 return -EINVAL;
5987 }
5988 start_log.flag = nla_get_u32(
5989 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5990 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5991
5992 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305993 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5994 !vos_isPktStatsEnabled()))
5995
Sushant Kaushik8e644982015-09-23 12:18:54 +05305996 {
5997 hddLog(LOGE, FL("per pkt stats not enabled"));
5998 return -EINVAL;
5999 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306000
Sushant Kaushik33200572015-08-05 16:46:20 +05306001 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306002 return 0;
6003}
6004
6005/**
6006 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6007 * or disable the collection of packet statistics from the firmware
6008 * @wiphy: WIPHY structure pointer
6009 * @wdev: Wireless device structure pointer
6010 * @data: Pointer to the data received
6011 * @data_len: Length of the data received
6012 *
6013 * This function is used to enable or disable the collection of packet
6014 * statistics from the firmware
6015 *
6016 * Return: 0 on success and errno on failure
6017 */
6018static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6019 struct wireless_dev *wdev,
6020 const void *data,
6021 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306022{
6023 int ret = 0;
6024
6025 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306026
6027 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6028 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306029 vos_ssr_unprotect(__func__);
6030
6031 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306032}
6033
6034
Agarwal Ashish738843c2014-09-25 12:27:56 +05306035static const struct nla_policy
6036wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6037 +1] =
6038{
6039 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6040};
6041
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306042static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306043 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306044 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306045 int data_len)
6046{
6047 struct net_device *dev = wdev->netdev;
6048 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6049 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6050 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6051 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6052 eHalStatus status;
6053 u32 dfsFlag = 0;
6054
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306055 ENTER();
6056
Agarwal Ashish738843c2014-09-25 12:27:56 +05306057 status = wlan_hdd_validate_context(pHddCtx);
6058 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306059 return -EINVAL;
6060 }
6061 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6062 data, data_len,
6063 wlan_hdd_set_no_dfs_flag_config_policy)) {
6064 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6065 return -EINVAL;
6066 }
6067
6068 /* Parse and fetch required bandwidth kbps */
6069 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6070 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6071 return -EINVAL;
6072 }
6073
6074 dfsFlag = nla_get_u32(
6075 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6076 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6077 dfsFlag);
6078
6079 pHddCtx->disable_dfs_flag = dfsFlag;
6080
6081 sme_disable_dfs_channel(hHal, dfsFlag);
6082 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306083
6084 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306085 return 0;
6086}
Atul Mittal115287b2014-07-08 13:26:33 +05306087
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306088static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6089 struct wireless_dev *wdev,
6090 const void *data,
6091 int data_len)
6092{
6093 int ret = 0;
6094
6095 vos_ssr_protect(__func__);
6096 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6097 vos_ssr_unprotect(__func__);
6098
6099 return ret;
6100
6101}
6102
Mukul Sharma2a271632014-10-13 14:59:01 +05306103const struct
6104nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6105{
6106 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306107 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6108 .type = NLA_UNSPEC,
6109 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306110};
6111
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306112static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306113 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306114{
6115
6116 u8 bssid[6] = {0};
6117 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6118 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6119 eHalStatus status = eHAL_STATUS_SUCCESS;
6120 v_U32_t isFwrRoamEnabled = FALSE;
6121 int ret;
6122
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306123 ENTER();
6124
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306125 ret = wlan_hdd_validate_context(pHddCtx);
6126 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306127 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306128 }
6129
6130 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6131 data, data_len,
6132 qca_wlan_vendor_attr);
6133 if (ret){
6134 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6135 return -EINVAL;
6136 }
6137
6138 /* Parse and fetch Enable flag */
6139 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6140 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6141 return -EINVAL;
6142 }
6143
6144 isFwrRoamEnabled = nla_get_u32(
6145 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6146
6147 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6148
6149 /* Parse and fetch bssid */
6150 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6151 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6152 return -EINVAL;
6153 }
6154
6155 memcpy(bssid, nla_data(
6156 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6157 sizeof(bssid));
6158 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6159
6160 //Update roaming
6161 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306162 if (!HAL_STATUS_SUCCESS(status)) {
6163 hddLog(LOGE,
6164 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6165 return -EINVAL;
6166 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306167 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306168 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306169}
6170
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306171static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6172 struct wireless_dev *wdev, const void *data, int data_len)
6173{
6174 int ret = 0;
6175
6176 vos_ssr_protect(__func__);
6177 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6178 vos_ssr_unprotect(__func__);
6179
6180 return ret;
6181}
6182
Sushant Kaushik847890c2015-09-28 16:05:17 +05306183static const struct
6184nla_policy
6185qca_wlan_vendor_get_wifi_info_policy[
6186 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6187 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6188 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6189};
6190
6191
6192/**
6193 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6194 * @wiphy: pointer to wireless wiphy structure.
6195 * @wdev: pointer to wireless_dev structure.
6196 * @data: Pointer to the data to be passed via vendor interface
6197 * @data_len:Length of the data to be passed
6198 *
6199 * This is called when wlan driver needs to send wifi driver related info
6200 * (driver/fw version) to the user space application upon request.
6201 *
6202 * Return: Return the Success or Failure code.
6203 */
6204static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6205 struct wireless_dev *wdev,
6206 const void *data, int data_len)
6207{
6208 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6209 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6210 tSirVersionString version;
6211 uint32 version_len;
6212 uint8 attr;
6213 int status;
6214 struct sk_buff *reply_skb = NULL;
6215
6216 if (VOS_FTM_MODE == hdd_get_conparam()) {
6217 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6218 return -EINVAL;
6219 }
6220
6221 status = wlan_hdd_validate_context(hdd_ctx);
6222 if (0 != status) {
6223 hddLog(LOGE, FL("HDD context is not valid"));
6224 return -EINVAL;
6225 }
6226
6227 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6228 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6229 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6230 return -EINVAL;
6231 }
6232
6233 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6234 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6235 QWLAN_VERSIONSTR);
6236 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6237 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6238 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6239 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6240 hdd_ctx->fw_Version);
6241 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6242 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6243 } else {
6244 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6245 return -EINVAL;
6246 }
6247
6248 version_len = strlen(version);
6249 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6250 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6251 if (!reply_skb) {
6252 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6253 return -ENOMEM;
6254 }
6255
6256 if (nla_put(reply_skb, attr, version_len, version)) {
6257 hddLog(LOGE, FL("nla put fail"));
6258 kfree_skb(reply_skb);
6259 return -EINVAL;
6260 }
6261
6262 return cfg80211_vendor_cmd_reply(reply_skb);
6263}
6264
6265/**
6266 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6267 * @wiphy: pointer to wireless wiphy structure.
6268 * @wdev: pointer to wireless_dev structure.
6269 * @data: Pointer to the data to be passed via vendor interface
6270 * @data_len:Length of the data to be passed
6271 * @data_len: Length of the data received
6272 *
6273 * This function is used to enable or disable the collection of packet
6274 * statistics from the firmware
6275 *
6276 * Return: 0 on success and errno on failure
6277 */
6278
6279static int
6280wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6281 struct wireless_dev *wdev,
6282 const void *data, int data_len)
6283
6284
6285{
6286 int ret = 0;
6287
6288 vos_ssr_protect(__func__);
6289 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6290 wdev, data, data_len);
6291 vos_ssr_unprotect(__func__);
6292
6293 return ret;
6294}
6295
6296
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306297/*
6298 * define short names for the global vendor params
6299 * used by __wlan_hdd_cfg80211_monitor_rssi()
6300 */
6301#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6302#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6303#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6304#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6305#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6306
6307/**---------------------------------------------------------------------------
6308
6309 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6310 monitor start is completed successfully.
6311
6312 \return - None
6313
6314 --------------------------------------------------------------------------*/
6315void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6316{
6317 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6318
6319 if (NULL == pHddCtx)
6320 {
6321 hddLog(VOS_TRACE_LEVEL_ERROR,
6322 "%s: HDD context is NULL",__func__);
6323 return;
6324 }
6325
6326 if (VOS_STATUS_SUCCESS == status)
6327 {
6328 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6329 }
6330 else
6331 {
6332 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6333 }
6334
6335 return;
6336}
6337
6338/**---------------------------------------------------------------------------
6339
6340 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6341 stop is completed successfully.
6342
6343 \return - None
6344
6345 --------------------------------------------------------------------------*/
6346void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6347{
6348 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6349
6350 if (NULL == pHddCtx)
6351 {
6352 hddLog(VOS_TRACE_LEVEL_ERROR,
6353 "%s: HDD context is NULL",__func__);
6354 return;
6355 }
6356
6357 if (VOS_STATUS_SUCCESS == status)
6358 {
6359 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6360 }
6361 else
6362 {
6363 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6364 }
6365
6366 return;
6367}
6368
6369/**
6370 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6371 * @wiphy: Pointer to wireless phy
6372 * @wdev: Pointer to wireless device
6373 * @data: Pointer to data
6374 * @data_len: Data length
6375 *
6376 * Return: 0 on success, negative errno on failure
6377 */
6378
6379static int
6380__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6381 struct wireless_dev *wdev,
6382 const void *data,
6383 int data_len)
6384{
6385 struct net_device *dev = wdev->netdev;
6386 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6387 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6388 hdd_station_ctx_t *pHddStaCtx;
6389 struct nlattr *tb[PARAM_MAX + 1];
6390 tpSirRssiMonitorReq pReq;
6391 eHalStatus status;
6392 int ret;
6393 uint32_t control;
6394 static const struct nla_policy policy[PARAM_MAX + 1] = {
6395 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6396 [PARAM_CONTROL] = { .type = NLA_U32 },
6397 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6398 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6399 };
6400
6401 ENTER();
6402
6403 ret = wlan_hdd_validate_context(hdd_ctx);
6404 if (0 != ret) {
6405 return -EINVAL;
6406 }
6407
6408 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6409 hddLog(LOGE, FL("Not in Connected state!"));
6410 return -ENOTSUPP;
6411 }
6412
6413 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6414 hddLog(LOGE, FL("Invalid ATTR"));
6415 return -EINVAL;
6416 }
6417
6418 if (!tb[PARAM_REQUEST_ID]) {
6419 hddLog(LOGE, FL("attr request id failed"));
6420 return -EINVAL;
6421 }
6422
6423 if (!tb[PARAM_CONTROL]) {
6424 hddLog(LOGE, FL("attr control failed"));
6425 return -EINVAL;
6426 }
6427
6428 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6429
6430 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6431 if(NULL == pReq)
6432 {
6433 hddLog(LOGE,
6434 FL("vos_mem_alloc failed "));
6435 return eHAL_STATUS_FAILED_ALLOC;
6436 }
6437 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6438
6439 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6440 pReq->sessionId = pAdapter->sessionId;
6441 pReq->rssiMonitorCbContext = hdd_ctx;
6442 control = nla_get_u32(tb[PARAM_CONTROL]);
6443 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6444
6445 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6446 pReq->requestId, pReq->sessionId, control);
6447
6448 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6449 if (!tb[PARAM_MIN_RSSI]) {
6450 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306451 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306452 }
6453
6454 if (!tb[PARAM_MAX_RSSI]) {
6455 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306456 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306457 }
6458
6459 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6460 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6461 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6462
6463 if (!(pReq->minRssi < pReq->maxRssi)) {
6464 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6465 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306466 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306467 }
6468 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6469 pReq->minRssi, pReq->maxRssi);
6470 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6471
6472 }
6473 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6474 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6475 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6476 }
6477 else {
6478 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306479 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306480 }
6481
6482 if (!HAL_STATUS_SUCCESS(status)) {
6483 hddLog(LOGE,
6484 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306485 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306486 }
6487
6488 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306489fail:
6490 vos_mem_free(pReq);
6491 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306492}
6493
6494/*
6495 * done with short names for the global vendor params
6496 * used by __wlan_hdd_cfg80211_monitor_rssi()
6497 */
6498#undef PARAM_MAX
6499#undef PARAM_CONTROL
6500#undef PARAM_REQUEST_ID
6501#undef PARAM_MAX_RSSI
6502#undef PARAM_MIN_RSSI
6503
6504/**
6505 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6506 * @wiphy: wiphy structure pointer
6507 * @wdev: Wireless device structure pointer
6508 * @data: Pointer to the data received
6509 * @data_len: Length of @data
6510 *
6511 * Return: 0 on success; errno on failure
6512 */
6513static int
6514wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6515 const void *data, int data_len)
6516{
6517 int ret;
6518
6519 vos_ssr_protect(__func__);
6520 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6521 vos_ssr_unprotect(__func__);
6522
6523 return ret;
6524}
6525
6526/**
6527 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6528 * @hddctx: HDD context
6529 * @data: rssi breached event data
6530 *
6531 * This function reads the rssi breached event %data and fill in the skb with
6532 * NL attributes and send up the NL event.
6533 * This callback execute in atomic context and must not invoke any
6534 * blocking calls.
6535 *
6536 * Return: none
6537 */
6538void hdd_rssi_threshold_breached_cb(void *hddctx,
6539 struct rssi_breach_event *data)
6540{
6541 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6542 int status;
6543 struct sk_buff *skb;
6544
6545 ENTER();
6546 status = wlan_hdd_validate_context(pHddCtx);
6547
6548 if (0 != status) {
6549 return;
6550 }
6551
6552 if (!data) {
6553 hddLog(LOGE, FL("data is null"));
6554 return;
6555 }
6556
6557 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6558#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6559 NULL,
6560#endif
6561 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6562 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6563 GFP_KERNEL);
6564
6565 if (!skb) {
6566 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6567 return;
6568 }
6569
6570 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6571 data->request_id, data->curr_rssi);
6572 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6573 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6574
6575 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6576 data->request_id) ||
6577 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6578 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6579 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6580 data->curr_rssi)) {
6581 hddLog(LOGE, FL("nla put fail"));
6582 goto fail;
6583 }
6584
6585 cfg80211_vendor_event(skb, GFP_KERNEL);
6586 return;
6587
6588fail:
6589 kfree_skb(skb);
6590 return;
6591}
6592
6593
6594
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306595/**
6596 * __wlan_hdd_cfg80211_setband() - set band
6597 * @wiphy: Pointer to wireless phy
6598 * @wdev: Pointer to wireless device
6599 * @data: Pointer to data
6600 * @data_len: Data length
6601 *
6602 * Return: 0 on success, negative errno on failure
6603 */
6604static int
6605__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6606 struct wireless_dev *wdev,
6607 const void *data,
6608 int data_len)
6609{
6610 struct net_device *dev = wdev->netdev;
6611 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6612 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6613 int ret;
6614 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6615 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6616
6617 ENTER();
6618
6619 ret = wlan_hdd_validate_context(hdd_ctx);
6620 if (0 != ret) {
6621 hddLog(LOGE, FL("HDD context is not valid"));
6622 return ret;
6623 }
6624
6625 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6626 policy)) {
6627 hddLog(LOGE, FL("Invalid ATTR"));
6628 return -EINVAL;
6629 }
6630
6631 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6632 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6633 return -EINVAL;
6634 }
6635
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306636 hdd_ctx->isSetBandByNL = TRUE;
6637 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306638 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306639 hdd_ctx->isSetBandByNL = FALSE;
6640
6641 EXIT();
6642 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306643}
6644
6645/**
6646 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6647 * @wiphy: wiphy structure pointer
6648 * @wdev: Wireless device structure pointer
6649 * @data: Pointer to the data received
6650 * @data_len: Length of @data
6651 *
6652 * Return: 0 on success; errno on failure
6653 */
6654static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6655 struct wireless_dev *wdev,
6656 const void *data,
6657 int data_len)
6658{
6659 int ret = 0;
6660
6661 vos_ssr_protect(__func__);
6662 ret = __wlan_hdd_cfg80211_setband(wiphy,
6663 wdev, data, data_len);
6664 vos_ssr_unprotect(__func__);
6665
6666 return ret;
6667}
6668
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306669#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6670/**
6671 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6672 * @hdd_ctx: HDD context
6673 * @request_id: [input] request id
6674 * @pattern_id: [output] pattern id
6675 *
6676 * This function loops through request id to pattern id array
6677 * if the slot is available, store the request id and return pattern id
6678 * if entry exists, return the pattern id
6679 *
6680 * Return: 0 on success and errno on failure
6681 */
6682static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6683 uint32_t request_id,
6684 uint8_t *pattern_id)
6685{
6686 uint32_t i;
6687
6688 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6689 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6690 {
6691 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6692 {
6693 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6694 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6695 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6696 return 0;
6697 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6698 request_id) {
6699 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6700 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6701 return 0;
6702 }
6703 }
6704 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6705 return -EINVAL;
6706}
6707
6708/**
6709 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6710 * @hdd_ctx: HDD context
6711 * @request_id: [input] request id
6712 * @pattern_id: [output] pattern id
6713 *
6714 * This function loops through request id to pattern id array
6715 * reset request id to 0 (slot available again) and
6716 * return pattern id
6717 *
6718 * Return: 0 on success and errno on failure
6719 */
6720static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6721 uint32_t request_id,
6722 uint8_t *pattern_id)
6723{
6724 uint32_t i;
6725
6726 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6727 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6728 {
6729 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6730 {
6731 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6732 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6733 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6734 return 0;
6735 }
6736 }
6737 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6738 return -EINVAL;
6739}
6740
6741
6742/*
6743 * define short names for the global vendor params
6744 * used by __wlan_hdd_cfg80211_offloaded_packets()
6745 */
6746#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6747#define PARAM_REQUEST_ID \
6748 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6749#define PARAM_CONTROL \
6750 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6751#define PARAM_IP_PACKET \
6752 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6753#define PARAM_SRC_MAC_ADDR \
6754 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6755#define PARAM_DST_MAC_ADDR \
6756 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6757#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6758
6759/**
6760 * wlan_hdd_add_tx_ptrn() - add tx pattern
6761 * @adapter: adapter pointer
6762 * @hdd_ctx: hdd context
6763 * @tb: nl attributes
6764 *
6765 * This function reads the NL attributes and forms a AddTxPtrn message
6766 * posts it to SME.
6767 *
6768 */
6769static int
6770wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6771 struct nlattr **tb)
6772{
6773 struct sSirAddPeriodicTxPtrn *add_req;
6774 eHalStatus status;
6775 uint32_t request_id, ret, len;
6776 uint8_t pattern_id = 0;
6777 v_MACADDR_t dst_addr;
6778 uint16_t eth_type = htons(ETH_P_IP);
6779
6780 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6781 {
6782 hddLog(LOGE, FL("Not in Connected state!"));
6783 return -ENOTSUPP;
6784 }
6785
6786 add_req = vos_mem_malloc(sizeof(*add_req));
6787 if (!add_req)
6788 {
6789 hddLog(LOGE, FL("memory allocation failed"));
6790 return -ENOMEM;
6791 }
6792
6793 /* Parse and fetch request Id */
6794 if (!tb[PARAM_REQUEST_ID])
6795 {
6796 hddLog(LOGE, FL("attr request id failed"));
6797 goto fail;
6798 }
6799
6800 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6801 hddLog(LOG1, FL("Request Id: %u"), request_id);
6802 if (request_id == 0)
6803 {
6804 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306805 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306806 }
6807
6808 if (!tb[PARAM_PERIOD])
6809 {
6810 hddLog(LOGE, FL("attr period failed"));
6811 goto fail;
6812 }
6813 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6814 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6815 if (add_req->usPtrnIntervalMs == 0)
6816 {
6817 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6818 goto fail;
6819 }
6820
6821 if (!tb[PARAM_SRC_MAC_ADDR])
6822 {
6823 hddLog(LOGE, FL("attr source mac address failed"));
6824 goto fail;
6825 }
6826 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6827 VOS_MAC_ADDR_SIZE);
6828 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6829 MAC_ADDR_ARRAY(add_req->macAddress));
6830
6831 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6832 VOS_MAC_ADDR_SIZE))
6833 {
6834 hddLog(LOGE,
6835 FL("input src mac address and connected ap bssid are different"));
6836 goto fail;
6837 }
6838
6839 if (!tb[PARAM_DST_MAC_ADDR])
6840 {
6841 hddLog(LOGE, FL("attr dst mac address failed"));
6842 goto fail;
6843 }
6844 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6845 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6846 MAC_ADDR_ARRAY(dst_addr.bytes));
6847
6848 if (!tb[PARAM_IP_PACKET])
6849 {
6850 hddLog(LOGE, FL("attr ip packet failed"));
6851 goto fail;
6852 }
6853 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6854 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6855
6856 if (add_req->ucPtrnSize < 0 ||
6857 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6858 HDD_ETH_HEADER_LEN))
6859 {
6860 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6861 add_req->ucPtrnSize);
6862 goto fail;
6863 }
6864
6865 len = 0;
6866 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6867 len += VOS_MAC_ADDR_SIZE;
6868 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6869 VOS_MAC_ADDR_SIZE);
6870 len += VOS_MAC_ADDR_SIZE;
6871 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6872 len += 2;
6873
6874 /*
6875 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6876 * ------------------------------------------------------------
6877 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6878 * ------------------------------------------------------------
6879 */
6880 vos_mem_copy(&add_req->ucPattern[len],
6881 nla_data(tb[PARAM_IP_PACKET]),
6882 add_req->ucPtrnSize);
6883 add_req->ucPtrnSize += len;
6884
6885 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6886 add_req->ucPattern, add_req->ucPtrnSize);
6887
6888 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6889 if (ret)
6890 {
6891 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6892 goto fail;
6893 }
6894 add_req->ucPtrnId = pattern_id;
6895 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6896
6897 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6898 if (!HAL_STATUS_SUCCESS(status))
6899 {
6900 hddLog(LOGE,
6901 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6902 goto fail;
6903 }
6904
6905 EXIT();
6906 vos_mem_free(add_req);
6907 return 0;
6908
6909fail:
6910 vos_mem_free(add_req);
6911 return -EINVAL;
6912}
6913
6914/**
6915 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6916 * @adapter: adapter pointer
6917 * @hdd_ctx: hdd context
6918 * @tb: nl attributes
6919 *
6920 * This function reads the NL attributes and forms a DelTxPtrn message
6921 * posts it to SME.
6922 *
6923 */
6924static int
6925wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6926 struct nlattr **tb)
6927{
6928 struct sSirDelPeriodicTxPtrn *del_req;
6929 eHalStatus status;
6930 uint32_t request_id, ret;
6931 uint8_t pattern_id = 0;
6932
6933 /* Parse and fetch request Id */
6934 if (!tb[PARAM_REQUEST_ID])
6935 {
6936 hddLog(LOGE, FL("attr request id failed"));
6937 return -EINVAL;
6938 }
6939 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6940 if (request_id == 0)
6941 {
6942 hddLog(LOGE, FL("request_id cannot be zero"));
6943 return -EINVAL;
6944 }
6945
6946 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6947 if (ret)
6948 {
6949 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6950 return -EINVAL;
6951 }
6952
6953 del_req = vos_mem_malloc(sizeof(*del_req));
6954 if (!del_req)
6955 {
6956 hddLog(LOGE, FL("memory allocation failed"));
6957 return -ENOMEM;
6958 }
6959
6960 vos_mem_set(del_req, sizeof(*del_req), 0);
6961 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6962 VOS_MAC_ADDR_SIZE);
6963 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6964 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6965 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6966 request_id, pattern_id, del_req->ucPatternIdBitmap);
6967
6968 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6969 if (!HAL_STATUS_SUCCESS(status))
6970 {
6971 hddLog(LOGE,
6972 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6973 goto fail;
6974 }
6975
6976 EXIT();
6977 vos_mem_free(del_req);
6978 return 0;
6979
6980fail:
6981 vos_mem_free(del_req);
6982 return -EINVAL;
6983}
6984
6985
6986/**
6987 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6988 * @wiphy: Pointer to wireless phy
6989 * @wdev: Pointer to wireless device
6990 * @data: Pointer to data
6991 * @data_len: Data length
6992 *
6993 * Return: 0 on success, negative errno on failure
6994 */
6995static int
6996__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6997 struct wireless_dev *wdev,
6998 const void *data,
6999 int data_len)
7000{
7001 struct net_device *dev = wdev->netdev;
7002 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7003 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7004 struct nlattr *tb[PARAM_MAX + 1];
7005 uint8_t control;
7006 int ret;
7007 static const struct nla_policy policy[PARAM_MAX + 1] =
7008 {
7009 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7010 [PARAM_CONTROL] = { .type = NLA_U32 },
7011 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7012 .len = VOS_MAC_ADDR_SIZE },
7013 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7014 .len = VOS_MAC_ADDR_SIZE },
7015 [PARAM_PERIOD] = { .type = NLA_U32 },
7016 };
7017
7018 ENTER();
7019
7020 ret = wlan_hdd_validate_context(hdd_ctx);
7021 if (0 != ret)
7022 {
7023 hddLog(LOGE, FL("HDD context is not valid"));
7024 return ret;
7025 }
7026
7027 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7028 {
7029 hddLog(LOGE,
7030 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7031 return -ENOTSUPP;
7032 }
7033
7034 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7035 {
7036 hddLog(LOGE, FL("Invalid ATTR"));
7037 return -EINVAL;
7038 }
7039
7040 if (!tb[PARAM_CONTROL])
7041 {
7042 hddLog(LOGE, FL("attr control failed"));
7043 return -EINVAL;
7044 }
7045 control = nla_get_u32(tb[PARAM_CONTROL]);
7046 hddLog(LOG1, FL("Control: %d"), control);
7047
7048 if (control == WLAN_START_OFFLOADED_PACKETS)
7049 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7050 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7051 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7052 else
7053 {
7054 hddLog(LOGE, FL("Invalid control: %d"), control);
7055 return -EINVAL;
7056 }
7057}
7058
7059/*
7060 * done with short names for the global vendor params
7061 * used by __wlan_hdd_cfg80211_offloaded_packets()
7062 */
7063#undef PARAM_MAX
7064#undef PARAM_REQUEST_ID
7065#undef PARAM_CONTROL
7066#undef PARAM_IP_PACKET
7067#undef PARAM_SRC_MAC_ADDR
7068#undef PARAM_DST_MAC_ADDR
7069#undef PARAM_PERIOD
7070
7071/**
7072 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7073 * @wiphy: wiphy structure pointer
7074 * @wdev: Wireless device structure pointer
7075 * @data: Pointer to the data received
7076 * @data_len: Length of @data
7077 *
7078 * Return: 0 on success; errno on failure
7079 */
7080static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7081 struct wireless_dev *wdev,
7082 const void *data,
7083 int data_len)
7084{
7085 int ret = 0;
7086
7087 vos_ssr_protect(__func__);
7088 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7089 wdev, data, data_len);
7090 vos_ssr_unprotect(__func__);
7091
7092 return ret;
7093}
7094#endif
7095
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307096static const struct
7097nla_policy
7098qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307099 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7100 .type = NLA_BINARY,
7101 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307102};
7103
7104/**
7105 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7106 * get link properties like nss, rate flags and operating frequency for
7107 * the connection with the given peer.
7108 * @wiphy: WIPHY structure pointer
7109 * @wdev: Wireless device structure pointer
7110 * @data: Pointer to the data received
7111 * @data_len: Length of the data received
7112 *
7113 * This function return the above link properties on success.
7114 *
7115 * Return: 0 on success and errno on failure
7116 */
7117static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7118 struct wireless_dev *wdev,
7119 const void *data,
7120 int data_len)
7121{
7122 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7123 struct net_device *dev = wdev->netdev;
7124 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7125 hdd_station_ctx_t *hdd_sta_ctx;
7126 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7127 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7128 uint32_t sta_id;
7129 struct sk_buff *reply_skb;
7130 uint32_t rate_flags = 0;
7131 uint8_t nss;
7132 uint8_t final_rate_flags = 0;
7133 uint32_t freq;
7134 v_CONTEXT_t pVosContext = NULL;
7135 ptSapContext pSapCtx = NULL;
7136
7137 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7139 return -EINVAL;
7140 }
7141
7142 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7143 qca_wlan_vendor_attr_policy)) {
7144 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7145 return -EINVAL;
7146 }
7147
7148 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7149 hddLog(VOS_TRACE_LEVEL_ERROR,
7150 FL("Attribute peerMac not provided for mode=%d"),
7151 adapter->device_mode);
7152 return -EINVAL;
7153 }
7154
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307155 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7156 hddLog(VOS_TRACE_LEVEL_ERROR,
7157 FL("Attribute peerMac is invalid=%d"),
7158 adapter->device_mode);
7159 return -EINVAL;
7160 }
7161
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307162 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7163 sizeof(peer_mac));
7164 hddLog(VOS_TRACE_LEVEL_INFO,
7165 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7166 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7167
7168 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7169 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7170 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7171 if ((hdd_sta_ctx->conn_info.connState !=
7172 eConnectionState_Associated) ||
7173 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7174 VOS_MAC_ADDRESS_LEN)) {
7175 hddLog(VOS_TRACE_LEVEL_ERROR,
7176 FL("Not Associated to mac "MAC_ADDRESS_STR),
7177 MAC_ADDR_ARRAY(peer_mac));
7178 return -EINVAL;
7179 }
7180
7181 nss = 1; //pronto supports only one spatial stream
7182 freq = vos_chan_to_freq(
7183 hdd_sta_ctx->conn_info.operationChannel);
7184 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7185
7186 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7187 adapter->device_mode == WLAN_HDD_SOFTAP) {
7188
7189 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7190 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7191 if(pSapCtx == NULL){
7192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7193 FL("psapCtx is NULL"));
7194 return -ENOENT;
7195 }
7196
7197
7198 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7199 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7200 !vos_is_macaddr_broadcast(
7201 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7202 vos_mem_compare(
7203 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7204 peer_mac, VOS_MAC_ADDRESS_LEN))
7205 break;
7206 }
7207
7208 if (WLAN_MAX_STA_COUNT == sta_id) {
7209 hddLog(VOS_TRACE_LEVEL_ERROR,
7210 FL("No active peer with mac="MAC_ADDRESS_STR),
7211 MAC_ADDR_ARRAY(peer_mac));
7212 return -EINVAL;
7213 }
7214
7215 nss = 1; //pronto supports only one spatial stream
7216 freq = vos_chan_to_freq(
7217 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7218 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7219 } else {
7220 hddLog(VOS_TRACE_LEVEL_ERROR,
7221 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7222 MAC_ADDR_ARRAY(peer_mac));
7223 return -EINVAL;
7224 }
7225
7226 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7227 if (rate_flags & eHAL_TX_RATE_VHT80) {
7228 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7229 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7230 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7231 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7232 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7233 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7234 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7235 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7236 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7237 if (rate_flags & eHAL_TX_RATE_HT40)
7238 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7239 }
7240
7241 if (rate_flags & eHAL_TX_RATE_SGI) {
7242 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7243 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7244 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7245 }
7246 }
7247
7248 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7249 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7250
7251 if (NULL == reply_skb) {
7252 hddLog(VOS_TRACE_LEVEL_ERROR,
7253 FL("getLinkProperties: skb alloc failed"));
7254 return -EINVAL;
7255 }
7256
7257 if (nla_put_u8(reply_skb,
7258 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7259 nss) ||
7260 nla_put_u8(reply_skb,
7261 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7262 final_rate_flags) ||
7263 nla_put_u32(reply_skb,
7264 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7265 freq)) {
7266 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7267 kfree_skb(reply_skb);
7268 return -EINVAL;
7269 }
7270
7271 return cfg80211_vendor_cmd_reply(reply_skb);
7272}
7273
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307274#define BEACON_MISS_THRESH_2_4 \
7275 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7276#define BEACON_MISS_THRESH_5_0 \
7277 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307278#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7279#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7280#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7281#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307282#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7283 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307284
7285/**
7286 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7287 * vendor command
7288 *
7289 * @wiphy: wiphy device pointer
7290 * @wdev: wireless device pointer
7291 * @data: Vendor command data buffer
7292 * @data_len: Buffer length
7293 *
7294 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7295 *
7296 * Return: EOK or other error codes.
7297 */
7298
7299static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7300 struct wireless_dev *wdev,
7301 const void *data,
7302 int data_len)
7303{
7304 struct net_device *dev = wdev->netdev;
7305 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7306 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7307 hdd_station_ctx_t *pHddStaCtx;
7308 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7309 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307310 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307311 eHalStatus status;
7312 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307313 uint8_t hb_thresh_val;
7314
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307315 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7316 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7317 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307318 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7319 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7320 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307321 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7322 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307323 };
7324
7325 ENTER();
7326
7327 if (VOS_FTM_MODE == hdd_get_conparam()) {
7328 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7329 return -EINVAL;
7330 }
7331
7332 ret_val = wlan_hdd_validate_context(pHddCtx);
7333 if (ret_val) {
7334 return ret_val;
7335 }
7336
7337 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7338
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307339 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7340 hddLog(LOGE, FL("Invalid ATTR"));
7341 return -EINVAL;
7342 }
7343
7344 /* check the Wifi Capability */
7345 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7346 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7347 {
7348 hddLog(VOS_TRACE_LEVEL_ERROR,
7349 FL("WIFICONFIG not supported by Firmware"));
7350 return -EINVAL;
7351 }
7352
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307353 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7354 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7355 modifyRoamParamsReq.value =
7356 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7357
7358 if (eHAL_STATUS_SUCCESS !=
7359 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7360 {
7361 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7362 ret_val = -EINVAL;
7363 }
7364 return ret_val;
7365 }
7366
7367 /* Moved this down in order to provide provision to set beacon
7368 * miss penalty count irrespective of connection state.
7369 */
7370 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7371 hddLog(LOGE, FL("Not in Connected state!"));
7372 return -ENOTSUPP;
7373 }
7374
7375 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307376
7377 if (!pReq) {
7378 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7379 "%s: Not able to allocate memory for tSetWifiConfigParams",
7380 __func__);
7381 return eHAL_STATUS_E_MALLOC_FAILED;
7382 }
7383
7384 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7385
7386 pReq->sessionId = pAdapter->sessionId;
7387 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7388
7389 if (tb[PARAM_MODULATED_DTIM]) {
7390 pReq->paramValue = nla_get_u32(
7391 tb[PARAM_MODULATED_DTIM]);
7392 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7393 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307394 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307395 hdd_set_pwrparams(pHddCtx);
7396 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7397 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7398
7399 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7400 iw_full_power_cbfn, pAdapter,
7401 eSME_FULL_PWR_NEEDED_BY_HDD);
7402 }
7403 else
7404 {
7405 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7406 }
7407 }
7408
7409 if (tb[PARAM_STATS_AVG_FACTOR]) {
7410 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7411 pReq->paramValue = nla_get_u16(
7412 tb[PARAM_STATS_AVG_FACTOR]);
7413 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7414 pReq->paramType, pReq->paramValue);
7415 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7416
7417 if (eHAL_STATUS_SUCCESS != status)
7418 {
7419 vos_mem_free(pReq);
7420 pReq = NULL;
7421 ret_val = -EPERM;
7422 return ret_val;
7423 }
7424 }
7425
7426
7427 if (tb[PARAM_GUARD_TIME]) {
7428 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7429 pReq->paramValue = nla_get_u32(
7430 tb[PARAM_GUARD_TIME]);
7431 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7432 pReq->paramType, pReq->paramValue);
7433 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7434
7435 if (eHAL_STATUS_SUCCESS != status)
7436 {
7437 vos_mem_free(pReq);
7438 pReq = NULL;
7439 ret_val = -EPERM;
7440 return ret_val;
7441 }
7442
7443 }
7444
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307445 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7446 hb_thresh_val = nla_get_u8(
7447 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7448
7449 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7450 hb_thresh_val);
7451 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7452 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7453 NULL, eANI_BOOLEAN_FALSE);
7454
7455 status = sme_update_hb_threshold(
7456 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7457 WNI_CFG_HEART_BEAT_THRESHOLD,
7458 hb_thresh_val, eCSR_BAND_24);
7459 if (eHAL_STATUS_SUCCESS != status) {
7460 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7461 vos_mem_free(pReq);
7462 pReq = NULL;
7463 return -EPERM;
7464 }
7465 }
7466
7467 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7468 hb_thresh_val = nla_get_u8(
7469 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7470
7471 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
7472 hb_thresh_val);
7473 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7474 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7475 NULL, eANI_BOOLEAN_FALSE);
7476
7477 status = sme_update_hb_threshold(
7478 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7479 WNI_CFG_HEART_BEAT_THRESHOLD,
7480 hb_thresh_val, eCSR_BAND_5G);
7481 if (eHAL_STATUS_SUCCESS != status) {
7482 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7483 vos_mem_free(pReq);
7484 pReq = NULL;
7485 return -EPERM;
7486 }
7487 }
7488
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307489 EXIT();
7490 return ret_val;
7491}
7492
7493/**
7494 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7495 * vendor command
7496 *
7497 * @wiphy: wiphy device pointer
7498 * @wdev: wireless device pointer
7499 * @data: Vendor command data buffer
7500 * @data_len: Buffer length
7501 *
7502 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7503 *
7504 * Return: EOK or other error codes.
7505 */
7506static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7507 struct wireless_dev *wdev,
7508 const void *data,
7509 int data_len)
7510{
7511 int ret;
7512
7513 vos_ssr_protect(__func__);
7514 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7515 data, data_len);
7516 vos_ssr_unprotect(__func__);
7517
7518 return ret;
7519}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307520
7521/*
7522 * define short names for the global vendor params
7523 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7524 */
7525#define STATS_SET_INVALID \
7526 QCA_ATTR_NUD_STATS_SET_INVALID
7527#define STATS_SET_START \
7528 QCA_ATTR_NUD_STATS_SET_START
7529#define STATS_GW_IPV4 \
7530 QCA_ATTR_NUD_STATS_GW_IPV4
7531#define STATS_SET_MAX \
7532 QCA_ATTR_NUD_STATS_SET_MAX
7533
7534const struct nla_policy
7535qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
7536{
7537 [STATS_SET_START] = {.type = NLA_FLAG },
7538 [STATS_GW_IPV4] = {.type = NLA_U32 },
7539};
7540
7541/**
7542 * hdd_set_nud_stats_cb() - hdd callback api to get status
7543 * @data: pointer to adapter
7544 * @rsp: status
7545 *
7546 * Return: None
7547 */
7548static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
7549{
7550
7551 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7552
7553 if (NULL == adapter)
7554 return;
7555
7556 if (VOS_STATUS_SUCCESS == rsp) {
7557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7558 "%s success received STATS_SET_START", __func__);
7559 } else {
7560 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7561 "%s STATS_SET_START Failed!!", __func__);
7562 }
7563 return;
7564}
7565
7566/**
7567 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7568 * @wiphy: pointer to wireless wiphy structure.
7569 * @wdev: pointer to wireless_dev structure.
7570 * @data: pointer to apfind configuration data.
7571 * @data_len: the length in byte of apfind data.
7572 *
7573 * This is called when wlan driver needs to send arp stats to
7574 * firmware.
7575 *
7576 * Return: An error code or 0 on success.
7577 */
7578static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7579 struct wireless_dev *wdev,
7580 const void *data, int data_len)
7581{
7582 struct nlattr *tb[STATS_SET_MAX + 1];
7583 struct net_device *dev = wdev->netdev;
7584 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7585 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05307586 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307587 setArpStatsParams arp_stats_params;
7588 int err = 0;
7589
7590 ENTER();
7591
7592 err = wlan_hdd_validate_context(hdd_ctx);
7593 if (0 != err)
7594 return err;
7595
7596 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
7597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7598 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
7599 return -EINVAL;
7600 }
7601
7602 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
7603 qca_wlan_vendor_set_nud_stats);
7604 if (err)
7605 {
7606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7607 "%s STATS_SET_START ATTR", __func__);
7608 return err;
7609 }
7610
7611 if (tb[STATS_SET_START])
7612 {
7613 if (!tb[STATS_GW_IPV4]) {
7614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7615 "%s STATS_SET_START CMD", __func__);
7616 return -EINVAL;
7617 }
7618 arp_stats_params.flag = true;
7619 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
7620 } else {
7621 arp_stats_params.flag = false;
7622 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05307623 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7625 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05307626 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
7627 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307628
7629 arp_stats_params.pkt_type = 1; // ARP packet type
7630
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05307631 if (arp_stats_params.flag) {
7632 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
7633 WLANTL_SetARPFWDatapath(pVosContext, true);
7634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7635 "%s Set FW in data path for ARP with tgt IP :%d",
7636 __func__, hdd_ctx->track_arp_ip);
7637 }
7638 else {
7639 WLANTL_SetARPFWDatapath(pVosContext, false);
7640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7641 "%s Remove FW from data path", __func__);
7642 }
7643
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307644 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
7645 arp_stats_params.data_ctx = adapter;
7646
7647 if (eHAL_STATUS_SUCCESS !=
7648 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
7649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7650 "%s STATS_SET_START CMD Failed!!", __func__);
7651 return -EINVAL;
7652 }
7653
7654 EXIT();
7655
7656 return err;
7657}
7658
7659/**
7660 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7661 * @wiphy: pointer to wireless wiphy structure.
7662 * @wdev: pointer to wireless_dev structure.
7663 * @data: pointer to apfind configuration data.
7664 * @data_len: the length in byte of apfind data.
7665 *
7666 * This is called when wlan driver needs to send arp stats to
7667 * firmware.
7668 *
7669 * Return: An error code or 0 on success.
7670 */
7671static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7672 struct wireless_dev *wdev,
7673 const void *data, int data_len)
7674{
7675 int ret;
7676
7677 vos_ssr_protect(__func__);
7678 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
7679 vos_ssr_unprotect(__func__);
7680
7681 return ret;
7682}
7683#undef STATS_SET_INVALID
7684#undef STATS_SET_START
7685#undef STATS_GW_IPV4
7686#undef STATS_SET_MAX
7687
7688/*
7689 * define short names for the global vendor params
7690 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7691 */
7692#define STATS_GET_INVALID \
7693 QCA_ATTR_NUD_STATS_SET_INVALID
7694#define COUNT_FROM_NETDEV \
7695 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
7696#define COUNT_TO_LOWER_MAC \
7697 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
7698#define RX_COUNT_BY_LOWER_MAC \
7699 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
7700#define COUNT_TX_SUCCESS \
7701 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
7702#define RSP_RX_COUNT_BY_LOWER_MAC \
7703 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
7704#define RSP_RX_COUNT_BY_UPPER_MAC \
7705 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
7706#define RSP_COUNT_TO_NETDEV \
7707 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
7708#define RSP_COUNT_OUT_OF_ORDER_DROP \
7709 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
7710#define AP_LINK_ACTIVE \
7711 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
7712#define AP_LINK_DAD \
7713 QCA_ATTR_NUD_STATS_AP_LINK_DAD
7714#define STATS_GET_MAX \
7715 QCA_ATTR_NUD_STATS_GET_MAX
7716
7717const struct nla_policy
7718qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
7719{
7720 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
7721 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
7722 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
7723 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
7724 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
7725 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
7726 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
7727 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
7728 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
7729 [AP_LINK_DAD] = {.type = NLA_FLAG },
7730};
7731
7732static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
7733{
7734
7735 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7736 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7737 struct hdd_nud_stats_context *context;
7738 int status;
7739
7740 ENTER();
7741
7742 if (NULL == adapter)
7743 return;
7744
7745 status = wlan_hdd_validate_context(hdd_ctx);
7746 if (0 != status) {
7747 return;
7748 }
7749
7750 if (!rsp) {
7751 hddLog(LOGE, FL("data is null"));
7752 return;
7753 }
7754
7755 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
7756 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
7757 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
7758 adapter->dad |= rsp->dad;
7759
7760 spin_lock(&hdd_context_lock);
7761 context = &hdd_ctx->nud_stats_context;
7762 complete(&context->response_event);
7763 spin_unlock(&hdd_context_lock);
7764
7765 return;
7766}
7767static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
7768 struct wireless_dev *wdev,
7769 const void *data, int data_len)
7770{
7771 int err = 0;
7772 unsigned long rc;
7773 struct hdd_nud_stats_context *context;
7774 struct net_device *dev = wdev->netdev;
7775 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7776 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7777 getArpStatsParams arp_stats_params;
7778 struct sk_buff *skb;
7779
7780 ENTER();
7781
7782 err = wlan_hdd_validate_context(hdd_ctx);
7783 if (0 != err)
7784 return err;
7785
7786 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
7787 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
7788 arp_stats_params.data_ctx = adapter;
7789
7790 spin_lock(&hdd_context_lock);
7791 context = &hdd_ctx->nud_stats_context;
7792 INIT_COMPLETION(context->response_event);
7793 spin_unlock(&hdd_context_lock);
7794
7795 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
7796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7797 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
7798 return -EINVAL;
7799 }
7800
7801 if (eHAL_STATUS_SUCCESS !=
7802 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
7803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7804 "%s STATS_SET_START CMD Failed!!", __func__);
7805 return -EINVAL;
7806 }
7807
7808 rc = wait_for_completion_timeout(&context->response_event,
7809 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
7810 if (!rc)
7811 {
7812 hddLog(LOGE,
7813 FL("Target response timed out request "));
7814 return -ETIMEDOUT;
7815 }
7816
7817 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7818 WLAN_NUD_STATS_LEN);
7819 if (!skb)
7820 {
7821 hddLog(VOS_TRACE_LEVEL_ERROR,
7822 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
7823 __func__);
7824 return -ENOMEM;
7825 }
7826
7827 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
7828 adapter->hdd_stats.hddArpStats.txCount) ||
7829 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
7830 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
7831 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
7832 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
7833 nla_put_u16(skb, COUNT_TX_SUCCESS,
7834 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
7835 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
7836 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
7837 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
7838 adapter->hdd_stats.hddArpStats.rxCount) ||
7839 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
7840 adapter->hdd_stats.hddArpStats.rxDelivered) ||
7841 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
7842 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
7843 hddLog(LOGE, FL("nla put fail"));
7844 kfree_skb(skb);
7845 return -EINVAL;
7846 }
7847 if (adapter->con_status)
7848 nla_put_flag(skb, AP_LINK_ACTIVE);
7849 if (adapter->dad)
7850 nla_put_flag(skb, AP_LINK_DAD);
7851
7852 cfg80211_vendor_cmd_reply(skb);
7853 return err;
7854}
7855
7856static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
7857 struct wireless_dev *wdev,
7858 const void *data, int data_len)
7859{
7860 int ret;
7861
7862 vos_ssr_protect(__func__);
7863 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
7864 vos_ssr_unprotect(__func__);
7865
7866 return ret;
7867}
7868
7869#undef QCA_ATTR_NUD_STATS_SET_INVALID
7870#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
7871#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
7872#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
7873#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
7874#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
7875#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
7876#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
7877#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
7878#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
7879#undef QCA_ATTR_NUD_STATS_GET_MAX
7880
7881
7882
Kapil Guptaee33bf12016-12-20 18:27:37 +05307883#ifdef WLAN_FEATURE_APFIND
7884/**
7885 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7886 * @wiphy: pointer to wireless wiphy structure.
7887 * @wdev: pointer to wireless_dev structure.
7888 * @data: pointer to apfind configuration data.
7889 * @data_len: the length in byte of apfind data.
7890 *
7891 * This is called when wlan driver needs to send APFIND configurations to
7892 * firmware.
7893 *
7894 * Return: An error code or 0 on success.
7895 */
7896static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7897 struct wireless_dev *wdev,
7898 const void *data, int data_len)
7899{
7900 struct sme_ap_find_request_req apfind_req;
7901 VOS_STATUS status;
7902 int ret_val;
7903 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7904
7905 ENTER();
7906
7907 ret_val = wlan_hdd_validate_context(hdd_ctx);
7908 if (ret_val)
7909 return ret_val;
7910
7911 if (VOS_FTM_MODE == hdd_get_conparam()) {
7912 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7913 return -EPERM;
7914 }
7915
7916 apfind_req.request_data_len = data_len;
7917 apfind_req.request_data = data;
7918
7919 status = sme_apfind_set_cmd(&apfind_req);
7920 if (VOS_STATUS_SUCCESS != status) {
7921 ret_val = -EIO;
7922 }
7923 return ret_val;
7924}
7925
7926/**
7927 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7928 * @wiphy: pointer to wireless wiphy structure.
7929 * @wdev: pointer to wireless_dev structure.
7930 * @data: pointer to apfind configuration data.
7931 * @data_len: the length in byte of apfind data.
7932 *
7933 * This is called when wlan driver needs to send APFIND configurations to
7934 * firmware.
7935 *
7936 * Return: An error code or 0 on success.
7937 */
7938static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7939 struct wireless_dev *wdev,
7940 const void *data, int data_len)
7941{
7942 int ret;
7943
7944 vos_ssr_protect(__func__);
7945 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
7946 vos_ssr_unprotect(__func__);
7947
7948 return ret;
7949}
7950#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307951const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7952{
Mukul Sharma2a271632014-10-13 14:59:01 +05307953 {
7954 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7955 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7956 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7957 WIPHY_VENDOR_CMD_NEED_NETDEV |
7958 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307959 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307960 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307961
7962 {
7963 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7964 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7965 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7966 WIPHY_VENDOR_CMD_NEED_NETDEV |
7967 WIPHY_VENDOR_CMD_NEED_RUNNING,
7968 .doit = wlan_hdd_cfg80211_nan_request
7969 },
7970
Sunil Duttc69bccb2014-05-26 21:30:20 +05307971#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7972 {
7973 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7974 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7975 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7976 WIPHY_VENDOR_CMD_NEED_NETDEV |
7977 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307978 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307979 },
7980
7981 {
7982 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7983 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7984 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7985 WIPHY_VENDOR_CMD_NEED_NETDEV |
7986 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307987 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307988 },
7989
7990 {
7991 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7992 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7993 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7994 WIPHY_VENDOR_CMD_NEED_NETDEV |
7995 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307996 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307997 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307998#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307999#ifdef WLAN_FEATURE_EXTSCAN
8000 {
8001 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8002 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8003 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8004 WIPHY_VENDOR_CMD_NEED_NETDEV |
8005 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308006 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308007 },
8008 {
8009 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8010 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8011 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8012 WIPHY_VENDOR_CMD_NEED_NETDEV |
8013 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308014 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308015 },
8016 {
8017 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8018 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8019 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8020 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308021 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308022 },
8023 {
8024 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8025 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8026 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8027 WIPHY_VENDOR_CMD_NEED_NETDEV |
8028 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308029 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308030 },
8031 {
8032 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8033 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8034 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8035 WIPHY_VENDOR_CMD_NEED_NETDEV |
8036 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308037 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308038 },
8039 {
8040 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8041 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8042 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8043 WIPHY_VENDOR_CMD_NEED_NETDEV |
8044 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308045 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308046 },
8047 {
8048 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8049 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8050 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8051 WIPHY_VENDOR_CMD_NEED_NETDEV |
8052 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308053 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308054 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308055#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308056/*EXT TDLS*/
8057 {
8058 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8059 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8060 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8061 WIPHY_VENDOR_CMD_NEED_NETDEV |
8062 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308063 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308064 },
8065 {
8066 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8067 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8068 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8069 WIPHY_VENDOR_CMD_NEED_NETDEV |
8070 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308071 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308072 },
8073 {
8074 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8075 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8076 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8077 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308078 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308079 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308080 {
8081 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8082 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8083 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8084 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308085 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308086 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308087 {
8088 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8089 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8090 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8091 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308092 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308093 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308094 {
8095 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8096 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8097 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8098 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308099 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308100 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308101 {
8102 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8103 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8104 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8105 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308106 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308107 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308108 {
8109 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308110 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8111 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8112 WIPHY_VENDOR_CMD_NEED_NETDEV |
8113 WIPHY_VENDOR_CMD_NEED_RUNNING,
8114 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8115 },
8116 {
8117 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308118 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8119 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8120 WIPHY_VENDOR_CMD_NEED_NETDEV |
8121 WIPHY_VENDOR_CMD_NEED_RUNNING,
8122 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308123 },
8124 {
8125 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8126 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8127 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8128 WIPHY_VENDOR_CMD_NEED_NETDEV,
8129 .doit = wlan_hdd_cfg80211_wifi_logger_start
8130 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308131 {
8132 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8133 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8134 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8135 WIPHY_VENDOR_CMD_NEED_NETDEV|
8136 WIPHY_VENDOR_CMD_NEED_RUNNING,
8137 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308138 },
8139 {
8140 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8141 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8142 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8143 WIPHY_VENDOR_CMD_NEED_NETDEV |
8144 WIPHY_VENDOR_CMD_NEED_RUNNING,
8145 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308146 },
8147 {
8148 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8149 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8150 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8151 WIPHY_VENDOR_CMD_NEED_NETDEV |
8152 WIPHY_VENDOR_CMD_NEED_RUNNING,
8153 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308154 },
8155#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8156 {
8157 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8158 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8159 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8160 WIPHY_VENDOR_CMD_NEED_NETDEV |
8161 WIPHY_VENDOR_CMD_NEED_RUNNING,
8162 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308163 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308164#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308165 {
8166 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8167 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8168 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8169 WIPHY_VENDOR_CMD_NEED_NETDEV |
8170 WIPHY_VENDOR_CMD_NEED_RUNNING,
8171 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308172 },
8173 {
8174 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8175 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8176 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8177 WIPHY_VENDOR_CMD_NEED_NETDEV |
8178 WIPHY_VENDOR_CMD_NEED_RUNNING,
8179 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308180 },
8181#ifdef WLAN_FEATURE_APFIND
8182 {
8183 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8184 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8185 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8186 WIPHY_VENDOR_CMD_NEED_NETDEV,
8187 .doit = wlan_hdd_cfg80211_apfind_cmd
8188 },
8189#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308190 {
8191 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8192 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8193 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8194 WIPHY_VENDOR_CMD_NEED_NETDEV |
8195 WIPHY_VENDOR_CMD_NEED_RUNNING,
8196 .doit = wlan_hdd_cfg80211_set_nud_stats
8197 },
8198 {
8199 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8200 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8201 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8202 WIPHY_VENDOR_CMD_NEED_NETDEV |
8203 WIPHY_VENDOR_CMD_NEED_RUNNING,
8204 .doit = wlan_hdd_cfg80211_get_nud_stats
8205 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308206 {
8207 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8208 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8209 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8210 WIPHY_VENDOR_CMD_NEED_NETDEV |
8211 WIPHY_VENDOR_CMD_NEED_RUNNING,
8212 .doit = hdd_cfg80211_get_station_cmd
8213 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308214};
8215
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008216/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308217static const
8218struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008219{
8220#ifdef FEATURE_WLAN_CH_AVOID
8221 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308222 .vendor_id = QCA_NL80211_VENDOR_ID,
8223 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008224 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308225#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8226#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8227 {
8228 /* Index = 1*/
8229 .vendor_id = QCA_NL80211_VENDOR_ID,
8230 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8231 },
8232 {
8233 /* Index = 2*/
8234 .vendor_id = QCA_NL80211_VENDOR_ID,
8235 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8236 },
8237 {
8238 /* Index = 3*/
8239 .vendor_id = QCA_NL80211_VENDOR_ID,
8240 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8241 },
8242 {
8243 /* Index = 4*/
8244 .vendor_id = QCA_NL80211_VENDOR_ID,
8245 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8246 },
8247 {
8248 /* Index = 5*/
8249 .vendor_id = QCA_NL80211_VENDOR_ID,
8250 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8251 },
8252 {
8253 /* Index = 6*/
8254 .vendor_id = QCA_NL80211_VENDOR_ID,
8255 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8256 },
8257#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308258#ifdef WLAN_FEATURE_EXTSCAN
8259 {
8260 .vendor_id = QCA_NL80211_VENDOR_ID,
8261 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8262 },
8263 {
8264 .vendor_id = QCA_NL80211_VENDOR_ID,
8265 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8266 },
8267 {
8268 .vendor_id = QCA_NL80211_VENDOR_ID,
8269 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8270 },
8271 {
8272 .vendor_id = QCA_NL80211_VENDOR_ID,
8273 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8274 },
8275 {
8276 .vendor_id = QCA_NL80211_VENDOR_ID,
8277 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8278 },
8279 {
8280 .vendor_id = QCA_NL80211_VENDOR_ID,
8281 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8282 },
8283 {
8284 .vendor_id = QCA_NL80211_VENDOR_ID,
8285 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8286 },
8287 {
8288 .vendor_id = QCA_NL80211_VENDOR_ID,
8289 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8290 },
8291 {
8292 .vendor_id = QCA_NL80211_VENDOR_ID,
8293 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8294 },
8295 {
8296 .vendor_id = QCA_NL80211_VENDOR_ID,
8297 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8298 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308299#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308300/*EXT TDLS*/
8301 {
8302 .vendor_id = QCA_NL80211_VENDOR_ID,
8303 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8304 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308305 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8306 .vendor_id = QCA_NL80211_VENDOR_ID,
8307 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8308 },
8309
Srinivas Dasari030bad32015-02-18 23:23:54 +05308310
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308311 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308312 .vendor_id = QCA_NL80211_VENDOR_ID,
8313 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8314 },
8315
Sushant Kaushik084f6592015-09-10 13:11:56 +05308316 {
8317 .vendor_id = QCA_NL80211_VENDOR_ID,
8318 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308319 },
8320 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8321 .vendor_id = QCA_NL80211_VENDOR_ID,
8322 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8323 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308324 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8325 .vendor_id = QCA_NL80211_VENDOR_ID,
8326 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8327 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308328 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8329 .vendor_id = QCA_NL80211_VENDOR_ID,
8330 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8331 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008332};
8333
Jeff Johnson295189b2012-06-20 16:38:30 -07008334/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308335 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308336 * This function is called by hdd_wlan_startup()
8337 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308338 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008339 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308340struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008341{
8342 struct wiphy *wiphy;
8343 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308344 /*
8345 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008346 */
8347 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8348
8349 if (!wiphy)
8350 {
8351 /* Print error and jump into err label and free the memory */
8352 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8353 return NULL;
8354 }
8355
Sunil Duttc69bccb2014-05-26 21:30:20 +05308356
Jeff Johnson295189b2012-06-20 16:38:30 -07008357 return wiphy;
8358}
8359
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308360#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8361 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8362/**
8363 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8364 * @wiphy: pointer to wiphy
8365 * @config: pointer to config
8366 *
8367 * Return: None
8368 */
8369static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8370 hdd_config_t *config)
8371{
8372 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8373 if (config->max_sched_scan_plan_interval)
8374 wiphy->max_sched_scan_plan_interval =
8375 config->max_sched_scan_plan_interval;
8376 if (config->max_sched_scan_plan_iterations)
8377 wiphy->max_sched_scan_plan_iterations =
8378 config->max_sched_scan_plan_iterations;
8379}
8380#else
8381static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8382 hdd_config_t *config)
8383{
8384}
8385#endif
8386
Jeff Johnson295189b2012-06-20 16:38:30 -07008387/*
8388 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308389 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008390 * private ioctl to change the band value
8391 */
8392int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8393{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308394 int i, j;
8395 eNVChannelEnabledType channelEnabledState;
8396
Jeff Johnsone7245742012-09-05 17:12:55 -07008397 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308398
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308399 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008400 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308401
8402 if (NULL == wiphy->bands[i])
8403 {
8404 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8405 __func__, i);
8406 continue;
8407 }
8408
8409 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8410 {
8411 struct ieee80211_supported_band *band = wiphy->bands[i];
8412
8413 channelEnabledState = vos_nv_getChannelEnabledState(
8414 band->channels[j].hw_value);
8415
8416 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
8417 {
Abhishek Singh678227a2014-11-04 10:52:38 +05308418 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308419 continue;
8420 }
8421 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
8422 {
8423 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8424 continue;
8425 }
8426
8427 if (NV_CHANNEL_DISABLE == channelEnabledState ||
8428 NV_CHANNEL_INVALID == channelEnabledState)
8429 {
8430 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8431 }
8432 else if (NV_CHANNEL_DFS == channelEnabledState)
8433 {
8434 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8435 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
8436 }
8437 else
8438 {
8439 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
8440 |IEEE80211_CHAN_RADAR);
8441 }
8442 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008443 }
8444 return 0;
8445}
8446/*
8447 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308448 * This function is called by hdd_wlan_startup()
8449 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008450 * This function is used to initialize and register wiphy structure.
8451 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308452int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008453 struct wiphy *wiphy,
8454 hdd_config_t *pCfg
8455 )
8456{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308457 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308458 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8459
Jeff Johnsone7245742012-09-05 17:12:55 -07008460 ENTER();
8461
Jeff Johnson295189b2012-06-20 16:38:30 -07008462 /* Now bind the underlying wlan device with wiphy */
8463 set_wiphy_dev(wiphy, dev);
8464
8465 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008466
Kiet Lam6c583332013-10-14 05:37:09 +05308467#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008468 /* the flag for the other case would be initialzed in
8469 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05308470#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8471 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
8472#else
Amar Singhal0a402232013-10-11 20:57:16 -07008473 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05308474#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05308475#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008476
Amar Singhalfddc28c2013-09-05 13:03:40 -07008477 /* This will disable updating of NL channels from passive to
8478 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308479#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8480 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
8481#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07008482 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308483#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07008484
Amar Singhala49cbc52013-10-08 18:37:44 -07008485
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008486#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008487 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
8488 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
8489 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07008490 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308491#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05308492 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308493#else
8494 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
8495#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008496#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008497
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008498#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008499 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08008500#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008501 || pCfg->isFastRoamIniFeatureEnabled
8502#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008503#ifdef FEATURE_WLAN_ESE
8504 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008505#endif
8506 )
8507 {
8508 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
8509 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08008510#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008511#ifdef FEATURE_WLAN_TDLS
8512 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
8513 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
8514#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308515#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05308516 if (pCfg->configPNOScanSupport)
8517 {
8518 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
8519 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
8520 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
8521 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
8522 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308523#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008524
Abhishek Singh10d85972015-04-17 10:27:23 +05308525#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8526 wiphy->features |= NL80211_FEATURE_HT_IBSS;
8527#endif
8528
Amar Singhalfddc28c2013-09-05 13:03:40 -07008529#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008530 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
8531 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07008532 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008533 driver need to determine what to do with both
8534 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07008535
8536 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07008537#else
8538 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008539#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008540
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308541 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8542
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308543 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008544
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308545 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8546
Jeff Johnson295189b2012-06-20 16:38:30 -07008547 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308548 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8549 | BIT(NL80211_IFTYPE_ADHOC)
8550 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8551 | BIT(NL80211_IFTYPE_P2P_GO)
8552 | BIT(NL80211_IFTYPE_AP);
8553
8554 if (VOS_MONITOR_MODE == hdd_get_conparam())
8555 {
8556 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
8557 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008558
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308559 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008560 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308561#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8562 if( pCfg->enableMCC )
8563 {
8564 /* Currently, supports up to two channels */
8565 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008566
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308567 if( !pCfg->allowMCCGODiffBI )
8568 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008569
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308570 }
8571 wiphy->iface_combinations = &wlan_hdd_iface_combination;
8572 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008573#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308574 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008575
Jeff Johnson295189b2012-06-20 16:38:30 -07008576 /* Before registering we need to update the ht capabilitied based
8577 * on ini values*/
8578 if( !pCfg->ShortGI20MhzEnable )
8579 {
8580 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8581 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008582 }
8583
8584 if( !pCfg->ShortGI40MhzEnable )
8585 {
8586 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8587 }
8588
8589 if( !pCfg->nChannelBondingMode5GHz )
8590 {
8591 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8592 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308593 /*
8594 * In case of static linked driver at the time of driver unload,
8595 * module exit doesn't happens. Module cleanup helps in cleaning
8596 * of static memory.
8597 * If driver load happens statically, at the time of driver unload,
8598 * wiphy flags don't get reset because of static memory.
8599 * It's better not to store channel in static memory.
8600 */
8601 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8602 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8603 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8604 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8605 {
8606 hddLog(VOS_TRACE_LEVEL_ERROR,
8607 FL("Not enough memory to allocate channels"));
8608 return -ENOMEM;
8609 }
8610 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8611 &hdd_channels_2_4_GHZ[0],
8612 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008613
Agrawal Ashish97dec502015-11-26 20:20:58 +05308614 if (true == hdd_is_5g_supported(pHddCtx))
8615 {
8616 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8617 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8618 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8619 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8620 {
8621 hddLog(VOS_TRACE_LEVEL_ERROR,
8622 FL("Not enough memory to allocate channels"));
8623 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8624 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8625 return -ENOMEM;
8626 }
8627 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8628 &hdd_channels_5_GHZ[0],
8629 sizeof(hdd_channels_5_GHZ));
8630 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308631
8632 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8633 {
8634
8635 if (NULL == wiphy->bands[i])
8636 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308637 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308638 __func__, i);
8639 continue;
8640 }
8641
8642 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8643 {
8644 struct ieee80211_supported_band *band = wiphy->bands[i];
8645
8646 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8647 {
8648 // Enable social channels for P2P
8649 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8650 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8651 else
8652 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8653 continue;
8654 }
8655 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8656 {
8657 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8658 continue;
8659 }
8660 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008661 }
8662 /*Initialise the supported cipher suite details*/
8663 wiphy->cipher_suites = hdd_cipher_suites;
8664 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8665
8666 /*signal strength in mBm (100*dBm) */
8667 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8668
8669#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308670 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008671#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008672
Sunil Duttc69bccb2014-05-26 21:30:20 +05308673 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8674 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008675 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8676 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8677
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308678 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
8679
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308680 EXIT();
8681 return 0;
8682}
8683
8684/* In this function we are registering wiphy. */
8685int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8686{
8687 ENTER();
8688 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008689 if (0 > wiphy_register(wiphy))
8690 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308691 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008692 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8693 return -EIO;
8694 }
8695
8696 EXIT();
8697 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308698}
Jeff Johnson295189b2012-06-20 16:38:30 -07008699
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308700/* In this function we are updating channel list when,
8701 regulatory domain is FCC and country code is US.
8702 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8703 As per FCC smart phone is not a indoor device.
8704 GO should not opeate on indoor channels */
8705void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8706{
8707 int j;
8708 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8709 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8710 //Default counrtycode from NV at the time of wiphy initialization.
8711 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8712 &defaultCountryCode[0]))
8713 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008714 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308715 }
8716 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8717 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308718 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8719 {
8720 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8721 return;
8722 }
8723 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8724 {
8725 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8726 // Mark UNII -1 band channel as passive
8727 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8728 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8729 }
8730 }
8731}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308732/* This function registers for all frame which supplicant is interested in */
8733void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008734{
Jeff Johnson295189b2012-06-20 16:38:30 -07008735 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8736 /* Register for all P2P action, public action etc frames */
8737 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008738 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308739 /* Register frame indication call back */
8740 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008741 /* Right now we are registering these frame when driver is getting
8742 initialized. Once we will move to 2.6.37 kernel, in which we have
8743 frame register ops, we will move this code as a part of that */
8744 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308745 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008746 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8747
8748 /* GAS Initial Response */
8749 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8750 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308751
Jeff Johnson295189b2012-06-20 16:38:30 -07008752 /* GAS Comeback Request */
8753 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8754 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8755
8756 /* GAS Comeback Response */
8757 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8758 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8759
8760 /* P2P Public Action */
8761 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308762 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008763 P2P_PUBLIC_ACTION_FRAME_SIZE );
8764
8765 /* P2P Action */
8766 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8767 (v_U8_t*)P2P_ACTION_FRAME,
8768 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008769
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308770 /* WNM BSS Transition Request frame */
8771 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8772 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8773 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008774
8775 /* WNM-Notification */
8776 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8777 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8778 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008779}
8780
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308781void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008782{
Jeff Johnson295189b2012-06-20 16:38:30 -07008783 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8784 /* Register for all P2P action, public action etc frames */
8785 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8786
Jeff Johnsone7245742012-09-05 17:12:55 -07008787 ENTER();
8788
Jeff Johnson295189b2012-06-20 16:38:30 -07008789 /* Right now we are registering these frame when driver is getting
8790 initialized. Once we will move to 2.6.37 kernel, in which we have
8791 frame register ops, we will move this code as a part of that */
8792 /* GAS Initial Request */
8793
8794 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8795 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8796
8797 /* GAS Initial Response */
8798 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8799 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308800
Jeff Johnson295189b2012-06-20 16:38:30 -07008801 /* GAS Comeback Request */
8802 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8803 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8804
8805 /* GAS Comeback Response */
8806 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8807 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8808
8809 /* P2P Public Action */
8810 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308811 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008812 P2P_PUBLIC_ACTION_FRAME_SIZE );
8813
8814 /* P2P Action */
8815 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8816 (v_U8_t*)P2P_ACTION_FRAME,
8817 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008818 /* WNM-Notification */
8819 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8820 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8821 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008822}
8823
8824#ifdef FEATURE_WLAN_WAPI
8825void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308826 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008827{
8828 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8829 tCsrRoamSetKey setKey;
8830 v_BOOL_t isConnected = TRUE;
8831 int status = 0;
8832 v_U32_t roamId= 0xFF;
8833 tANI_U8 *pKeyPtr = NULL;
8834 int n = 0;
8835
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308836 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8837 __func__, hdd_device_modetoString(pAdapter->device_mode),
8838 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008839
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308840 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008841 setKey.keyId = key_index; // Store Key ID
8842 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8843 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8844 setKey.paeRole = 0 ; // the PAE role
8845 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8846 {
8847 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8848 }
8849 else
8850 {
8851 isConnected = hdd_connIsConnected(pHddStaCtx);
8852 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8853 }
8854 setKey.keyLength = key_Len;
8855 pKeyPtr = setKey.Key;
8856 memcpy( pKeyPtr, key, key_Len);
8857
Arif Hussain6d2a3322013-11-17 19:50:10 -08008858 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008859 __func__, key_Len);
8860 for (n = 0 ; n < key_Len; n++)
8861 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8862 __func__,n,setKey.Key[n]);
8863
8864 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8865 if ( isConnected )
8866 {
8867 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8868 pAdapter->sessionId, &setKey, &roamId );
8869 }
8870 if ( status != 0 )
8871 {
8872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8873 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8874 __LINE__, status );
8875 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8876 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308877 /* Need to clear any trace of key value in the memory.
8878 * Thus zero out the memory even though it is local
8879 * variable.
8880 */
8881 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008882}
8883#endif /* FEATURE_WLAN_WAPI*/
8884
8885#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308886int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008887 beacon_data_t **ppBeacon,
8888 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008889#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308890int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008891 beacon_data_t **ppBeacon,
8892 struct cfg80211_beacon_data *params,
8893 int dtim_period)
8894#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308895{
Jeff Johnson295189b2012-06-20 16:38:30 -07008896 int size;
8897 beacon_data_t *beacon = NULL;
8898 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05308899 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
8900 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07008901
Jeff Johnsone7245742012-09-05 17:12:55 -07008902 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008903 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308904 {
8905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8906 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008907 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308908 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008909
8910 old = pAdapter->sessionCtx.ap.beacon;
8911
8912 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308913 {
8914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8915 FL("session(%d) old and new heads points to NULL"),
8916 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008917 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308918 }
8919
8920 if (params->tail && !params->tail_len)
8921 {
8922 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8923 FL("tail_len is zero but tail is not NULL"));
8924 return -EINVAL;
8925 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008926
Jeff Johnson295189b2012-06-20 16:38:30 -07008927#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8928 /* Kernel 3.0 is not updating dtim_period for set beacon */
8929 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308930 {
8931 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8932 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008933 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308934 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008935#endif
8936
Kapil Gupta137ef892016-12-13 19:38:00 +05308937 if (params->head)
8938 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008939 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308940 head = params->head;
8941 } else
8942 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008943 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308944 head = old->head;
8945 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008946
Kapil Gupta137ef892016-12-13 19:38:00 +05308947 if (params->tail || !old)
8948 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008949 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308950 tail = params->tail;
8951 } else
8952 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008953 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308954 tail = old->tail;
8955 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008956
Kapil Gupta137ef892016-12-13 19:38:00 +05308957 if (params->proberesp_ies || !old)
8958 {
8959 proberesp_ies_len = params->proberesp_ies_len;
8960 proberesp_ies = params->proberesp_ies;
8961 } else
8962 {
8963 proberesp_ies_len = old->proberesp_ies_len;
8964 proberesp_ies = old->proberesp_ies;
8965 }
8966
8967 if (params->assocresp_ies || !old)
8968 {
8969 assocresp_ies_len = params->assocresp_ies_len;
8970 assocresp_ies = params->assocresp_ies;
8971 } else
8972 {
8973 assocresp_ies_len = old->assocresp_ies_len;
8974 assocresp_ies = old->assocresp_ies;
8975 }
8976
8977 size = sizeof(beacon_data_t) + head_len + tail_len +
8978 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07008979
8980 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008981 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308982 {
8983 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8984 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008985 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308986 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008987
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008988#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05308989 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07008990 beacon->dtim_period = params->dtim_period;
8991 else
8992 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008993#else
Kapil Gupta137ef892016-12-13 19:38:00 +05308994 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008995 beacon->dtim_period = dtim_period;
8996 else
8997 beacon->dtim_period = old->dtim_period;
8998#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308999
Jeff Johnson295189b2012-06-20 16:38:30 -07009000 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9001 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309002 beacon->proberesp_ies = beacon->tail + tail_len;
9003 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9004
Jeff Johnson295189b2012-06-20 16:38:30 -07009005 beacon->head_len = head_len;
9006 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309007 beacon->proberesp_ies_len = proberesp_ies_len;
9008 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009009
c_manjee527ecac2017-01-25 12:25:27 +05309010 if (head && head_len)
9011 memcpy(beacon->head, head, head_len);
9012 if (tail && tail_len)
9013 memcpy(beacon->tail, tail, tail_len);
9014 if (proberesp_ies && proberesp_ies_len)
9015 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9016 if (assocresp_ies && assocresp_ies_len)
9017 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009018
9019 *ppBeacon = beacon;
9020
9021 kfree(old);
9022
9023 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009024}
Jeff Johnson295189b2012-06-20 16:38:30 -07009025
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309026v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9027#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9028 const v_U8_t *pIes,
9029#else
9030 v_U8_t *pIes,
9031#endif
9032 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009033{
9034 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309035 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009036 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309037
Jeff Johnson295189b2012-06-20 16:38:30 -07009038 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309039 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009040 elem_id = ptr[0];
9041 elem_len = ptr[1];
9042 left -= 2;
9043 if(elem_len > left)
9044 {
9045 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009046 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009047 eid,elem_len,left);
9048 return NULL;
9049 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309050 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009051 {
9052 return ptr;
9053 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309054
Jeff Johnson295189b2012-06-20 16:38:30 -07009055 left -= elem_len;
9056 ptr += (elem_len + 2);
9057 }
9058 return NULL;
9059}
9060
Jeff Johnson295189b2012-06-20 16:38:30 -07009061/* Check if rate is 11g rate or not */
9062static int wlan_hdd_rate_is_11g(u8 rate)
9063{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009064 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009065 u8 i;
9066 for (i = 0; i < 8; i++)
9067 {
9068 if(rate == gRateArray[i])
9069 return TRUE;
9070 }
9071 return FALSE;
9072}
9073
9074/* Check for 11g rate and set proper 11g only mode */
9075static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9076 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9077{
9078 u8 i, num_rates = pIe[0];
9079
9080 pIe += 1;
9081 for ( i = 0; i < num_rates; i++)
9082 {
9083 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9084 {
9085 /* If rate set have 11g rate than change the mode to 11G */
9086 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9087 if (pIe[i] & BASIC_RATE_MASK)
9088 {
9089 /* If we have 11g rate as basic rate, it means mode
9090 is 11g only mode.
9091 */
9092 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9093 *pCheckRatesfor11g = FALSE;
9094 }
9095 }
9096 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9097 {
9098 *require_ht = TRUE;
9099 }
9100 }
9101 return;
9102}
9103
9104static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9105{
9106 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9107 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9108 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9109 u8 checkRatesfor11g = TRUE;
9110 u8 require_ht = FALSE;
9111 u8 *pIe=NULL;
9112
9113 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9114
9115 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9116 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9117 if (pIe != NULL)
9118 {
9119 pIe += 1;
9120 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9121 &pConfig->SapHw_mode);
9122 }
9123
9124 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9125 WLAN_EID_EXT_SUPP_RATES);
9126 if (pIe != NULL)
9127 {
9128
9129 pIe += 1;
9130 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9131 &pConfig->SapHw_mode);
9132 }
9133
9134 if( pConfig->channel > 14 )
9135 {
9136 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9137 }
9138
9139 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9140 WLAN_EID_HT_CAPABILITY);
9141
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309142 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009143 {
9144 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9145 if(require_ht)
9146 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9147 }
9148}
9149
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309150static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9151 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9152{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009153 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309154 v_U8_t *pIe = NULL;
9155 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9156
9157 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9158 pBeacon->tail, pBeacon->tail_len);
9159
9160 if (pIe)
9161 {
9162 ielen = pIe[1] + 2;
9163 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9164 {
9165 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9166 }
9167 else
9168 {
9169 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9170 return -EINVAL;
9171 }
9172 *total_ielen += ielen;
9173 }
9174 return 0;
9175}
9176
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009177static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9178 v_U8_t *genie, v_U8_t *total_ielen)
9179{
9180 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9181 int left = pBeacon->tail_len;
9182 v_U8_t *ptr = pBeacon->tail;
9183 v_U8_t elem_id, elem_len;
9184 v_U16_t ielen = 0;
9185
9186 if ( NULL == ptr || 0 == left )
9187 return;
9188
9189 while (left >= 2)
9190 {
9191 elem_id = ptr[0];
9192 elem_len = ptr[1];
9193 left -= 2;
9194 if (elem_len > left)
9195 {
9196 hddLog( VOS_TRACE_LEVEL_ERROR,
9197 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9198 elem_id, elem_len, left);
9199 return;
9200 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309201 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009202 {
9203 /* skipping the VSIE's which we don't want to include or
9204 * it will be included by existing code
9205 */
9206 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9207#ifdef WLAN_FEATURE_WFD
9208 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9209#endif
9210 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9211 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9212 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9213 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9214 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9215 {
9216 ielen = ptr[1] + 2;
9217 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9218 {
9219 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9220 *total_ielen += ielen;
9221 }
9222 else
9223 {
9224 hddLog( VOS_TRACE_LEVEL_ERROR,
9225 "IE Length is too big "
9226 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9227 elem_id, elem_len, *total_ielen);
9228 }
9229 }
9230 }
9231
9232 left -= elem_len;
9233 ptr += (elem_len + 2);
9234 }
9235 return;
9236}
9237
Kapil Gupta137ef892016-12-13 19:38:00 +05309238int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009239{
9240 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309241 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009242 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009243 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309244 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009245
9246 genie = vos_mem_malloc(MAX_GENIE_LEN);
9247
9248 if(genie == NULL) {
9249
9250 return -ENOMEM;
9251 }
9252
Kapil Gupta137ef892016-12-13 19:38:00 +05309253 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309254 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9255 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009256 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309257 hddLog(LOGE,
9258 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309259 ret = -EINVAL;
9260 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009261 }
9262
9263#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309264 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9265 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9266 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309267 hddLog(LOGE,
9268 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309269 ret = -EINVAL;
9270 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009271 }
9272#endif
9273
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309274 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9275 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009276 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309277 hddLog(LOGE,
9278 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309279 ret = -EINVAL;
9280 goto done;
9281 }
9282
9283 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9284 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009285 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009286 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009287
9288 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9289 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9290 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9291 {
9292 hddLog(LOGE,
9293 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009294 ret = -EINVAL;
9295 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009296 }
9297
9298 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9299 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9300 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9301 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9302 ==eHAL_STATUS_FAILURE)
9303 {
9304 hddLog(LOGE,
9305 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009306 ret = -EINVAL;
9307 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009308 }
9309
9310 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309311 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009312 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309313 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009314 u8 probe_rsp_ie_len[3] = {0};
9315 u8 counter = 0;
9316 /* Check Probe Resp Length if it is greater then 255 then Store
9317 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9318 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9319 Store More then 255 bytes into One Variable.
9320 */
9321 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9322 {
9323 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9324 {
9325 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9326 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9327 }
9328 else
9329 {
9330 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9331 rem_probe_resp_ie_len = 0;
9332 }
9333 }
9334
9335 rem_probe_resp_ie_len = 0;
9336
9337 if (probe_rsp_ie_len[0] > 0)
9338 {
9339 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9340 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309341 (tANI_U8*)&pBeacon->
9342 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009343 probe_rsp_ie_len[0], NULL,
9344 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9345 {
9346 hddLog(LOGE,
9347 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009348 ret = -EINVAL;
9349 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009350 }
9351 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9352 }
9353
9354 if (probe_rsp_ie_len[1] > 0)
9355 {
9356 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9357 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05309358 (tANI_U8*)&pBeacon->
9359 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009360 probe_rsp_ie_len[1], NULL,
9361 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9362 {
9363 hddLog(LOGE,
9364 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009365 ret = -EINVAL;
9366 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009367 }
9368 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9369 }
9370
9371 if (probe_rsp_ie_len[2] > 0)
9372 {
9373 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9374 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05309375 (tANI_U8*)&pBeacon->
9376 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009377 probe_rsp_ie_len[2], NULL,
9378 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9379 {
9380 hddLog(LOGE,
9381 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009382 ret = -EINVAL;
9383 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009384 }
9385 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9386 }
9387
9388 if (probe_rsp_ie_len[1] == 0 )
9389 {
9390 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9391 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9392 eANI_BOOLEAN_FALSE) )
9393 {
9394 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009395 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009396 }
9397 }
9398
9399 if (probe_rsp_ie_len[2] == 0 )
9400 {
9401 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9402 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9403 eANI_BOOLEAN_FALSE) )
9404 {
9405 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009406 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009407 }
9408 }
9409
9410 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9411 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9412 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9413 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9414 == eHAL_STATUS_FAILURE)
9415 {
9416 hddLog(LOGE,
9417 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009418 ret = -EINVAL;
9419 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009420 }
9421 }
9422 else
9423 {
9424 // Reset WNI_CFG_PROBE_RSP Flags
9425 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
9426
9427 hddLog(VOS_TRACE_LEVEL_INFO,
9428 "%s: No Probe Response IE received in set beacon",
9429 __func__);
9430 }
9431
9432 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309433 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009434 {
9435 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05309436 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
9437 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07009438 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9439 {
9440 hddLog(LOGE,
9441 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009442 ret = -EINVAL;
9443 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009444 }
9445
9446 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9447 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
9448 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9449 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9450 == eHAL_STATUS_FAILURE)
9451 {
9452 hddLog(LOGE,
9453 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009454 ret = -EINVAL;
9455 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009456 }
9457 }
9458 else
9459 {
9460 hddLog(VOS_TRACE_LEVEL_INFO,
9461 "%s: No Assoc Response IE received in set beacon",
9462 __func__);
9463
9464 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9465 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9466 eANI_BOOLEAN_FALSE) )
9467 {
9468 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009469 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009470 }
9471 }
9472
Jeff Johnsone7245742012-09-05 17:12:55 -07009473done:
Jeff Johnson295189b2012-06-20 16:38:30 -07009474 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309475 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009476}
Jeff Johnson295189b2012-06-20 16:38:30 -07009477
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309478/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009479 * FUNCTION: wlan_hdd_validate_operation_channel
9480 * called by wlan_hdd_cfg80211_start_bss() and
9481 * wlan_hdd_cfg80211_set_channel()
9482 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309483 * channel list.
9484 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07009485VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009486{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309487
Jeff Johnson295189b2012-06-20 16:38:30 -07009488 v_U32_t num_ch = 0;
9489 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
9490 u32 indx = 0;
9491 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309492 v_U8_t fValidChannel = FALSE, count = 0;
9493 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309494
Jeff Johnson295189b2012-06-20 16:38:30 -07009495 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9496
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309497 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009498 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309499 /* Validate the channel */
9500 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009501 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309502 if ( channel == rfChannels[count].channelNum )
9503 {
9504 fValidChannel = TRUE;
9505 break;
9506 }
9507 }
9508 if (fValidChannel != TRUE)
9509 {
9510 hddLog(VOS_TRACE_LEVEL_ERROR,
9511 "%s: Invalid Channel [%d]", __func__, channel);
9512 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009513 }
9514 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309515 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009516 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309517 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
9518 valid_ch, &num_ch))
9519 {
9520 hddLog(VOS_TRACE_LEVEL_ERROR,
9521 "%s: failed to get valid channel list", __func__);
9522 return VOS_STATUS_E_FAILURE;
9523 }
9524 for (indx = 0; indx < num_ch; indx++)
9525 {
9526 if (channel == valid_ch[indx])
9527 {
9528 break;
9529 }
9530 }
9531
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309532 if (indx >= num_ch)
9533 {
9534 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9535 {
9536 eCsrBand band;
9537 unsigned int freq;
9538
9539 sme_GetFreqBand(hHal, &band);
9540
9541 if (eCSR_BAND_5G == band)
9542 {
9543#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9544 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9545 {
9546 freq = ieee80211_channel_to_frequency(channel,
9547 IEEE80211_BAND_2GHZ);
9548 }
9549 else
9550 {
9551 freq = ieee80211_channel_to_frequency(channel,
9552 IEEE80211_BAND_5GHZ);
9553 }
9554#else
9555 freq = ieee80211_channel_to_frequency(channel);
9556#endif
9557 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
9558 return VOS_STATUS_SUCCESS;
9559 }
9560 }
9561
9562 hddLog(VOS_TRACE_LEVEL_ERROR,
9563 "%s: Invalid Channel [%d]", __func__, channel);
9564 return VOS_STATUS_E_FAILURE;
9565 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009566 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309567
Jeff Johnson295189b2012-06-20 16:38:30 -07009568 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309569
Jeff Johnson295189b2012-06-20 16:38:30 -07009570}
9571
Viral Modi3a32cc52013-02-08 11:14:52 -08009572/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309573 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009574 * This function is used to set the channel number
9575 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309576static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009577 struct ieee80211_channel *chan,
9578 enum nl80211_channel_type channel_type
9579 )
9580{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309581 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009582 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009583 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009584 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309585 hdd_context_t *pHddCtx;
9586 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009587
9588 ENTER();
9589
9590 if( NULL == dev )
9591 {
9592 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009593 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009594 return -ENODEV;
9595 }
9596 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309597
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309598 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9599 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
9600 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08009601 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309602 "%s: device_mode = %s (%d) freq = %d", __func__,
9603 hdd_device_modetoString(pAdapter->device_mode),
9604 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309605
9606 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9607 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309608 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08009609 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309610 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009611 }
9612
9613 /*
9614 * Do freq to chan conversion
9615 * TODO: for 11a
9616 */
9617
9618 channel = ieee80211_frequency_to_channel(freq);
9619
9620 /* Check freq range */
9621 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9622 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9623 {
9624 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009625 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009626 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9627 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9628 return -EINVAL;
9629 }
9630
9631 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9632
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309633 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9634 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009635 {
9636 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
9637 {
9638 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009639 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009640 return -EINVAL;
9641 }
9642 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9643 "%s: set channel to [%d] for device mode =%d",
9644 __func__, channel,pAdapter->device_mode);
9645 }
9646 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009647 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009648 )
9649 {
9650 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9651 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9652 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9653
9654 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9655 {
9656 /* Link is up then return cant set channel*/
9657 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009658 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009659 return -EINVAL;
9660 }
9661
9662 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9663 pHddStaCtx->conn_info.operationChannel = channel;
9664 pRoamProfile->ChannelInfo.ChannelList =
9665 &pHddStaCtx->conn_info.operationChannel;
9666 }
9667 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009668 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009669 )
9670 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309671 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9672 {
9673 if(VOS_STATUS_SUCCESS !=
9674 wlan_hdd_validate_operation_channel(pAdapter,channel))
9675 {
9676 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009677 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309678 return -EINVAL;
9679 }
9680 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9681 }
9682 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009683 {
9684 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9685
9686 /* If auto channel selection is configured as enable/ 1 then ignore
9687 channel set by supplicant
9688 */
9689 if ( cfg_param->apAutoChannelSelection )
9690 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309691 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9692 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009693 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309694 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9695 __func__, hdd_device_modetoString(pAdapter->device_mode),
9696 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009697 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309698 else
9699 {
9700 if(VOS_STATUS_SUCCESS !=
9701 wlan_hdd_validate_operation_channel(pAdapter,channel))
9702 {
9703 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009704 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309705 return -EINVAL;
9706 }
9707 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9708 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009709 }
9710 }
9711 else
9712 {
9713 hddLog(VOS_TRACE_LEVEL_FATAL,
9714 "%s: Invalid device mode failed to set valid channel", __func__);
9715 return -EINVAL;
9716 }
9717 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309718 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009719}
9720
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309721static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9722 struct net_device *dev,
9723 struct ieee80211_channel *chan,
9724 enum nl80211_channel_type channel_type
9725 )
9726{
9727 int ret;
9728
9729 vos_ssr_protect(__func__);
9730 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9731 vos_ssr_unprotect(__func__);
9732
9733 return ret;
9734}
9735
Anurag Chouhan83026002016-12-13 22:46:21 +05309736#ifdef DHCP_SERVER_OFFLOAD
9737void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
9738 VOS_STATUS status)
9739{
9740 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
9741
9742 ENTER();
9743
9744 if (NULL == adapter)
9745 {
9746 hddLog(VOS_TRACE_LEVEL_ERROR,
9747 "%s: adapter is NULL",__func__);
9748 return;
9749 }
9750
9751 adapter->dhcp_status.dhcp_offload_status = status;
9752 vos_event_set(&adapter->dhcp_status.vos_event);
9753 return;
9754}
9755
9756/**
9757 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
9758 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309759 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +05309760 *
9761 * Return: None
9762 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309763VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
9764 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +05309765{
9766 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
9767 sir_dhcp_srv_offload_info dhcp_srv_info;
9768 tANI_U8 num_entries = 0;
9769 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
9770 tANI_U8 num;
9771 tANI_U32 temp;
9772 VOS_STATUS ret;
9773
9774 ENTER();
9775
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309776 if (!re_init) {
9777 ret = wlan_hdd_validate_context(hdd_ctx);
9778 if (0 != ret)
9779 return VOS_STATUS_E_INVAL;
9780 }
Anurag Chouhan83026002016-12-13 22:46:21 +05309781
9782 /* Prepare the request to send to SME */
9783 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
9784 if (NULL == dhcp_srv_info) {
9785 hddLog(VOS_TRACE_LEVEL_ERROR,
9786 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
9787 return VOS_STATUS_E_NOMEM;
9788 }
9789
9790 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
9791
9792 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
9793 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
9794 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
9795 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
9796 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
9797 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
9798
9799 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
9800 srv_ip,
9801 &num_entries,
Anurag Chouhanac145c22016-11-22 16:51:47 +05309802 IPADDR_NUM_ENTRIES, ".");
Anurag Chouhan83026002016-12-13 22:46:21 +05309803 if (num_entries != IPADDR_NUM_ENTRIES) {
9804 hddLog(VOS_TRACE_LEVEL_ERROR,
9805 "%s: incorrect IP address (%s) assigned for DHCP server!",
9806 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9807 vos_mem_free(dhcp_srv_info);
9808 return VOS_STATUS_E_FAILURE;
9809 }
9810
9811 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
9812 hddLog(VOS_TRACE_LEVEL_ERROR,
9813 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
9814 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9815 vos_mem_free(dhcp_srv_info);
9816 return VOS_STATUS_E_FAILURE;
9817 }
9818
9819 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
9820 hddLog(VOS_TRACE_LEVEL_ERROR,
9821 "%s: invalid IP address (%s)! The last field must be less than 100!",
9822 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9823 vos_mem_free(dhcp_srv_info);
9824 return VOS_STATUS_E_FAILURE;
9825 }
9826
9827 for (num = 0; num < num_entries; num++) {
9828 temp = srv_ip[num];
9829 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
9830 }
9831
9832 if (eHAL_STATUS_SUCCESS !=
9833 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
9834 hddLog(VOS_TRACE_LEVEL_ERROR,
9835 "%s: sme_set_dhcp_srv_offload fail!", __func__);
9836 vos_mem_free(dhcp_srv_info);
9837 return VOS_STATUS_E_FAILURE;
9838 }
9839
9840 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9841 "%s: enable DHCP Server offload successfully!", __func__);
9842
9843 vos_mem_free(dhcp_srv_info);
9844 return 0;
9845}
9846#endif /* DHCP_SERVER_OFFLOAD */
9847
Jeff Johnson295189b2012-06-20 16:38:30 -07009848#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9849static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9850 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009851#else
9852static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9853 struct cfg80211_beacon_data *params,
9854 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309855 enum nl80211_hidden_ssid hidden_ssid,
9856 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009857#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009858{
9859 tsap_Config_t *pConfig;
9860 beacon_data_t *pBeacon = NULL;
9861 struct ieee80211_mgmt *pMgmt_frame;
9862 v_U8_t *pIe=NULL;
9863 v_U16_t capab_info;
9864 eCsrAuthType RSNAuthType;
9865 eCsrEncryptionType RSNEncryptType;
9866 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309867 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009868 tpWLAN_SAPEventCB pSapEventCallback;
9869 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -07009870 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309871 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009872 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309873 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009874 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009875 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309876 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009877 v_BOOL_t MFPCapable = VOS_FALSE;
9878 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309879 v_BOOL_t sapEnable11AC =
9880 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +05309881 u_int16_t prev_rsn_length = 0;
9882
Jeff Johnson295189b2012-06-20 16:38:30 -07009883 ENTER();
9884
Nitesh Shah9b066282017-06-06 18:05:52 +05309885 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309886 iniConfig = pHddCtx->cfg_ini;
9887
Jeff Johnson295189b2012-06-20 16:38:30 -07009888 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9889
9890 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9891
9892 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9893
9894 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9895
9896 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9897
9898 //channel is already set in the set_channel Call back
9899 //pConfig->channel = pCommitConfig->channel;
9900
9901 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309902 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009903 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9904
9905 pConfig->dtim_period = pBeacon->dtim_period;
9906
Arif Hussain6d2a3322013-11-17 19:50:10 -08009907 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009908 pConfig->dtim_period);
9909
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009910 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009911 {
9912 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009913 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309914 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9915 {
9916 tANI_BOOLEAN restartNeeded;
9917 pConfig->ieee80211d = 1;
9918 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9919 sme_setRegInfo(hHal, pConfig->countryCode);
9920 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9921 }
9922 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009923 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009924 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009925 pConfig->ieee80211d = 1;
9926 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9927 sme_setRegInfo(hHal, pConfig->countryCode);
9928 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009929 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009930 else
9931 {
9932 pConfig->ieee80211d = 0;
9933 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309934 /*
9935 * If auto channel is configured i.e. channel is 0,
9936 * so skip channel validation.
9937 */
9938 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9939 {
9940 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9941 {
9942 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009943 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309944 return -EINVAL;
9945 }
9946 }
9947 else
9948 {
9949 if(1 != pHddCtx->is_dynamic_channel_range_set)
9950 {
9951 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9952 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9953 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9954 }
9955 pHddCtx->is_dynamic_channel_range_set = 0;
9956 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009957 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009958 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009959 {
9960 pConfig->ieee80211d = 0;
9961 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309962
9963#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9964 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9965 pConfig->authType = eSAP_OPEN_SYSTEM;
9966 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9967 pConfig->authType = eSAP_SHARED_KEY;
9968 else
9969 pConfig->authType = eSAP_AUTO_SWITCH;
9970#else
9971 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9972 pConfig->authType = eSAP_OPEN_SYSTEM;
9973 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9974 pConfig->authType = eSAP_SHARED_KEY;
9975 else
9976 pConfig->authType = eSAP_AUTO_SWITCH;
9977#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009978
9979 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309980
9981 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009982 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +05309983#ifdef SAP_AUTH_OFFLOAD
9984 /* In case of sap offload, hostapd.conf is configuted with open mode and
9985 * security is configured from ini file. Due to open mode in hostapd.conf
9986 * privacy bit is set to false which will result in not sending,
9987 * data packets as encrypted.
9988 * If enable_sap_auth_offload is enabled in ini and
9989 * sap_auth_offload_sec_type is type of WPA2-PSK,
9990 * driver will set privacy bit to 1.
9991 */
9992 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
9993 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
9994 pConfig->privacy = VOS_TRUE;
9995#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009996
9997 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9998
9999 /*Set wps station to configured*/
10000 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
10001
10002 if(pIe)
10003 {
10004 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
10005 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010006 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -070010007 return -EINVAL;
10008 }
10009 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
10010 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070010011 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070010012 /* Check 15 bit of WPS IE as it contain information for wps state
10013 * WPS state
10014 */
10015 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
10016 {
10017 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
10018 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
10019 {
10020 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
10021 }
10022 }
10023 }
10024 else
10025 {
10026 pConfig->wps_state = SAP_WPS_DISABLED;
10027 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010028 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070010029
c_hpothufe599e92014-06-16 11:38:55 +053010030 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10031 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10032 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
10033 eCSR_ENCRYPT_TYPE_NONE;
10034
Jeff Johnson295189b2012-06-20 16:38:30 -070010035 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053010036 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010037 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010038 WLAN_EID_RSN);
10039 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010040 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010041 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010042 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10043 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10044 pConfig->RSNWPAReqIELength);
10045 else
10046 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10047 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010048 /* The actual processing may eventually be more extensive than
10049 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070010050 * by the app.
10051 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010052 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010053 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10054 &RSNEncryptType,
10055 &mcRSNEncryptType,
10056 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010057 &MFPCapable,
10058 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010059 pConfig->RSNWPAReqIE[1]+2,
10060 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010061
10062 if( VOS_STATUS_SUCCESS == status )
10063 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010064 /* Now copy over all the security attributes you have
10065 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010066 * */
10067 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10068 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10069 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10070 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010071 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010072 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010073 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10074 }
10075 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010076
Jeff Johnson295189b2012-06-20 16:38:30 -070010077 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10078 pBeacon->tail, pBeacon->tail_len);
10079
10080 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
10081 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010082 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010083 {
10084 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053010085 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070010086 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010087 if (pConfig->RSNWPAReqIELength <=
10088 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
10089 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
10090 pIe[1] + 2);
10091 else
10092 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10093 pConfig->RSNWPAReqIELength);
10094
Jeff Johnson295189b2012-06-20 16:38:30 -070010095 }
10096 else
10097 {
10098 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010099 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10100 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10101 pConfig->RSNWPAReqIELength);
10102 else
10103 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10104 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010105 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010106 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10107 &RSNEncryptType,
10108 &mcRSNEncryptType,
10109 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010110 &MFPCapable,
10111 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010112 pConfig->RSNWPAReqIE[1]+2,
10113 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010114
10115 if( VOS_STATUS_SUCCESS == status )
10116 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010117 /* Now copy over all the security attributes you have
10118 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010119 * */
10120 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10121 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10122 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10123 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010124 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010125 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010126 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10127 }
10128 }
10129 }
10130
Kapil Gupta137ef892016-12-13 19:38:00 +053010131 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070010132 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
10133 return -EINVAL;
10134 }
10135
Jeff Johnson295189b2012-06-20 16:38:30 -070010136 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
10137
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010138#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010139 if (params->ssid != NULL)
10140 {
10141 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
10142 pConfig->SSIDinfo.ssid.length = params->ssid_len;
10143 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10144 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10145 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010146#else
10147 if (ssid != NULL)
10148 {
10149 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
10150 pConfig->SSIDinfo.ssid.length = ssid_len;
10151 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10152 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10153 }
10154#endif
10155
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010156 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070010157 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010158
Jeff Johnson295189b2012-06-20 16:38:30 -070010159 /* default value */
10160 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
10161 pConfig->num_accept_mac = 0;
10162 pConfig->num_deny_mac = 0;
10163
10164 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10165 pBeacon->tail, pBeacon->tail_len);
10166
10167 /* pIe for black list is following form:
10168 type : 1 byte
10169 length : 1 byte
10170 OUI : 4 bytes
10171 acl type : 1 byte
10172 no of mac addr in black list: 1 byte
10173 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010174 */
10175 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010176 {
10177 pConfig->SapMacaddr_acl = pIe[6];
10178 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010179 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010180 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010181 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
10182 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010183 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10184 for (i = 0; i < pConfig->num_deny_mac; i++)
10185 {
10186 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10187 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010188 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010189 }
10190 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10191 pBeacon->tail, pBeacon->tail_len);
10192
10193 /* pIe for white list is following form:
10194 type : 1 byte
10195 length : 1 byte
10196 OUI : 4 bytes
10197 acl type : 1 byte
10198 no of mac addr in white list: 1 byte
10199 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010200 */
10201 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010202 {
10203 pConfig->SapMacaddr_acl = pIe[6];
10204 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010205 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010206 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010207 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
10208 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010209 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10210 for (i = 0; i < pConfig->num_accept_mac; i++)
10211 {
10212 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10213 acl_entry++;
10214 }
10215 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010216
Jeff Johnson295189b2012-06-20 16:38:30 -070010217 wlan_hdd_set_sapHwmode(pHostapdAdapter);
10218
Jeff Johnsone7245742012-09-05 17:12:55 -070010219#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010220 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010221 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
10222 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053010223 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
10224 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010225 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
10226 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010227 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
10228 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070010229 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010230 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070010231 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010232 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010233
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010234 /* If ACS disable and selected channel <= 14
10235 * OR
10236 * ACS enabled and ACS operating band is choosen as 2.4
10237 * AND
10238 * VHT in 2.4G Disabled
10239 * THEN
10240 * Fallback to 11N mode
10241 */
10242 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
10243 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053010244 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010245 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010246 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010247 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
10248 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010249 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
10250 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010251 }
10252#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010253
Jeff Johnson295189b2012-06-20 16:38:30 -070010254 // ht_capab is not what the name conveys,this is used for protection bitmap
10255 pConfig->ht_capab =
10256 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
10257
Kapil Gupta137ef892016-12-13 19:38:00 +053010258 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010259 {
10260 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10261 return -EINVAL;
10262 }
10263
10264 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010265 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070010266 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
10267 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010268 pConfig->obssProtEnabled =
10269 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070010270
Chet Lanctot8cecea22014-02-11 19:09:36 -080010271#ifdef WLAN_FEATURE_11W
10272 pConfig->mfpCapable = MFPCapable;
10273 pConfig->mfpRequired = MFPRequired;
10274 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
10275 pConfig->mfpCapable, pConfig->mfpRequired);
10276#endif
10277
Arif Hussain6d2a3322013-11-17 19:50:10 -080010278 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070010279 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010280 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
10281 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
10282 (int)pConfig->channel);
10283 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
10284 pConfig->SapHw_mode, pConfig->privacy,
10285 pConfig->authType);
10286 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
10287 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
10288 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
10289 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070010290
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010291 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010292 {
10293 //Bss already started. just return.
10294 //TODO Probably it should update some beacon params.
10295 hddLog( LOGE, "Bss Already started...Ignore the request");
10296 EXIT();
10297 return 0;
10298 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010299
Agarwal Ashish51325b52014-06-16 16:50:49 +053010300 if (vos_max_concurrent_connections_reached()) {
10301 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10302 return -EINVAL;
10303 }
10304
Jeff Johnson295189b2012-06-20 16:38:30 -070010305 pConfig->persona = pHostapdAdapter->device_mode;
10306
Peng Xu2446a892014-09-05 17:21:18 +053010307 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
10308 if ( NULL != psmeConfig)
10309 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010310 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053010311 sme_GetConfigParam(hHal, psmeConfig);
10312 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010313#ifdef WLAN_FEATURE_AP_HT40_24G
10314 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
10315 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
10316 && pHddCtx->cfg_ini->apHT40_24GEnabled)
10317 {
10318 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
10319 sme_UpdateConfig (hHal, psmeConfig);
10320 }
10321#endif
Peng Xu2446a892014-09-05 17:21:18 +053010322 vos_mem_free(psmeConfig);
10323 }
Peng Xuafc34e32014-09-25 13:23:55 +053010324 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053010325
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010326 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10327
Jeff Johnson295189b2012-06-20 16:38:30 -070010328 pSapEventCallback = hdd_hostapd_SAPEventCB;
10329 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
10330 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
10331 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010332 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010333 ret = -EINVAL;
10334 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070010335 }
10336
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010337 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070010338 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
10339
10340 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010341
Jeff Johnson295189b2012-06-20 16:38:30 -070010342 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010343 {
10344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010345 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070010346 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010347 VOS_ASSERT(0);
10348 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010349
Jeff Johnson295189b2012-06-20 16:38:30 -070010350 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053010351 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
10352 VOS_STATUS_SUCCESS)
10353 {
10354 hddLog(LOGE,FL("Fail to get Softap sessionID"));
10355 VOS_ASSERT(0);
10356 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053010357 /* Initialize WMM configuation */
10358 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010359 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010360
Anurag Chouhan83026002016-12-13 22:46:21 +053010361#ifdef DHCP_SERVER_OFFLOAD
10362 /* set dhcp server offload */
10363 if (iniConfig->enable_dhcp_srv_offload &&
10364 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010365 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010366 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010367 if (!VOS_IS_STATUS_SUCCESS(status))
10368 {
10369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10370 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010371 vos_event_reset(&pHostapdState->vosEvent);
10372 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10373 status = vos_wait_single_event(&pHostapdState->vosEvent,
10374 10000);
10375 if (!VOS_IS_STATUS_SUCCESS(status)) {
10376 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010377 ret = -EINVAL;
10378 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010379 }
10380 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010381 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010382 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
10383 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
10384 {
10385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10386 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
10387 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010388 vos_event_reset(&pHostapdState->vosEvent);
10389 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10390 status = vos_wait_single_event(&pHostapdState->vosEvent,
10391 10000);
10392 if (!VOS_IS_STATUS_SUCCESS(status)) {
10393 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010394 ret = -EINVAL;
10395 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010396 }
10397 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010398 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010399#ifdef MDNS_OFFLOAD
10400 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010401 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010402 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
10403 if (VOS_IS_STATUS_SUCCESS(status))
10404 {
10405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10406 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010407 vos_event_reset(&pHostapdState->vosEvent);
10408 if (VOS_STATUS_SUCCESS ==
10409 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10410 status = vos_wait_single_event(&pHostapdState->vosEvent,
10411 10000);
10412 if (!VOS_IS_STATUS_SUCCESS(status)) {
10413 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010414 ret = -EINVAL;
10415 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010416 }
10417 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010418 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010419 status = vos_wait_single_event(&pHostapdAdapter->
10420 mdns_status.vos_event, 2000);
10421 if (!VOS_IS_STATUS_SUCCESS(status) ||
10422 pHostapdAdapter->mdns_status.mdns_enable_status ||
10423 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
10424 pHostapdAdapter->mdns_status.mdns_resp_status)
10425 {
10426 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10427 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
10428 pHostapdAdapter->mdns_status.mdns_enable_status,
10429 pHostapdAdapter->mdns_status.mdns_fqdn_status,
10430 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010431 vos_event_reset(&pHostapdState->vosEvent);
10432 if (VOS_STATUS_SUCCESS ==
10433 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10434 status = vos_wait_single_event(&pHostapdState->vosEvent,
10435 10000);
10436 if (!VOS_IS_STATUS_SUCCESS(status)) {
10437 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010438 ret = -EINVAL;
10439 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010440 }
10441 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010442 }
10443 }
10444#endif /* MDNS_OFFLOAD */
10445 } else {
10446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10447 ("DHCP Disabled ini %d, FW %d"),
10448 iniConfig->enable_dhcp_srv_offload,
10449 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053010450 }
10451#endif /* DHCP_SERVER_OFFLOAD */
10452
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010453#ifdef WLAN_FEATURE_P2P_DEBUG
10454 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
10455 {
10456 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
10457 {
10458 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10459 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010460 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010461 }
10462 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
10463 {
10464 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10465 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010466 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010467 }
10468 }
10469#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053010470 /* Check and restart SAP if it is on Unsafe channel */
10471 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010472
Jeff Johnson295189b2012-06-20 16:38:30 -070010473 pHostapdState->bCommit = TRUE;
10474 EXIT();
10475
10476 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010477error:
10478 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10479 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010480}
10481
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010482#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010483static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010484 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070010485 struct beacon_parameters *params)
10486{
10487 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010488 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010489 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010490
10491 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010492
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010493 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10494 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
10495 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010496 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
10497 hdd_device_modetoString(pAdapter->device_mode),
10498 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010499
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010500 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10501 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010502 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010503 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010504 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010505 }
10506
Agarwal Ashish51325b52014-06-16 16:50:49 +053010507 if (vos_max_concurrent_connections_reached()) {
10508 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10509 return -EINVAL;
10510 }
10511
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010512 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010513 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010514 )
10515 {
10516 beacon_data_t *old,*new;
10517
10518 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010519
Jeff Johnson295189b2012-06-20 16:38:30 -070010520 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010521 {
10522 hddLog(VOS_TRACE_LEVEL_WARN,
10523 FL("already beacon info added to session(%d)"),
10524 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010525 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010526 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010527
10528 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10529
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010530 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070010531 {
10532 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010533 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010534 return -EINVAL;
10535 }
10536
10537 pAdapter->sessionCtx.ap.beacon = new;
10538
10539 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10540 }
10541
10542 EXIT();
10543 return status;
10544}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010545
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010546static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
10547 struct net_device *dev,
10548 struct beacon_parameters *params)
10549{
10550 int ret;
10551
10552 vos_ssr_protect(__func__);
10553 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
10554 vos_ssr_unprotect(__func__);
10555
10556 return ret;
10557}
10558
10559static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010560 struct net_device *dev,
10561 struct beacon_parameters *params)
10562{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010563 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010564 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10565 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010566 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010567
10568 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010569
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010570 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10571 TRACE_CODE_HDD_CFG80211_SET_BEACON,
10572 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
10573 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10574 __func__, hdd_device_modetoString(pAdapter->device_mode),
10575 pAdapter->device_mode);
10576
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010577 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10578 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010579 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010580 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010581 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010582 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010583
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010584 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010585 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010586 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010587 {
10588 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010589
Jeff Johnson295189b2012-06-20 16:38:30 -070010590 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010591
Jeff Johnson295189b2012-06-20 16:38:30 -070010592 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010593 {
10594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10595 FL("session(%d) old and new heads points to NULL"),
10596 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010597 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010598 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010599
10600 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10601
10602 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010603 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010604 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010605 return -EINVAL;
10606 }
10607
10608 pAdapter->sessionCtx.ap.beacon = new;
10609
10610 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10611 }
10612
10613 EXIT();
10614 return status;
10615}
10616
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010617static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
10618 struct net_device *dev,
10619 struct beacon_parameters *params)
10620{
10621 int ret;
10622
10623 vos_ssr_protect(__func__);
10624 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
10625 vos_ssr_unprotect(__func__);
10626
10627 return ret;
10628}
10629
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010630#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10631
10632#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010633static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010634 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010635#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010636static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010637 struct net_device *dev)
10638#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010639{
10640 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070010641 hdd_context_t *pHddCtx = NULL;
10642 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010643 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010644 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010645
10646 ENTER();
10647
10648 if (NULL == pAdapter)
10649 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010650 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010651 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010652 return -ENODEV;
10653 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010654
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010655 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10656 TRACE_CODE_HDD_CFG80211_STOP_AP,
10657 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010658 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10659 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010660 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010661 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010662 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070010663 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010664
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010665 pScanInfo = &pHddCtx->scan_info;
10666
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010667 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10668 __func__, hdd_device_modetoString(pAdapter->device_mode),
10669 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010670
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010671 ret = wlan_hdd_scan_abort(pAdapter);
10672
Girish Gowli4bf7a632014-06-12 13:42:11 +053010673 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070010674 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10676 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010677
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010678 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070010679 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10681 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080010682
Jeff Johnsone7245742012-09-05 17:12:55 -070010683 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010684 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070010685 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010686 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010687 }
10688
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010689 /* Delete all associated STAs before stopping AP/P2P GO */
10690 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053010691 hdd_hostapd_stop(dev);
10692
Jeff Johnson295189b2012-06-20 16:38:30 -070010693 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010694 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010695 )
10696 {
10697 beacon_data_t *old;
10698
10699 old = pAdapter->sessionCtx.ap.beacon;
10700
10701 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010702 {
10703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10704 FL("session(%d) beacon data points to NULL"),
10705 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010706 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010707 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010708
Jeff Johnson295189b2012-06-20 16:38:30 -070010709 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010710
10711 mutex_lock(&pHddCtx->sap_lock);
10712 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10713 {
Jeff Johnson4416a782013-03-25 14:17:50 -070010714 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010715 {
10716 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10717
10718 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10719
10720 if (!VOS_IS_STATUS_SUCCESS(status))
10721 {
10722 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010723 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010724 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010725 }
10726 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010727 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010728 /* BSS stopped, clear the active sessions for this device mode */
10729 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010730 }
10731 mutex_unlock(&pHddCtx->sap_lock);
10732
10733 if(status != VOS_STATUS_SUCCESS)
10734 {
10735 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010736 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010737 return -EINVAL;
10738 }
10739
Jeff Johnson4416a782013-03-25 14:17:50 -070010740 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010741 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
10742 ==eHAL_STATUS_FAILURE)
10743 {
10744 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010745 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010746 }
10747
Jeff Johnson4416a782013-03-25 14:17:50 -070010748 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010749 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10750 eANI_BOOLEAN_FALSE) )
10751 {
10752 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010753 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010754 }
10755
10756 // Reset WNI_CFG_PROBE_RSP Flags
10757 wlan_hdd_reset_prob_rspies(pAdapter);
10758
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010759 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
10760
Jeff Johnson295189b2012-06-20 16:38:30 -070010761 pAdapter->sessionCtx.ap.beacon = NULL;
10762 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010763#ifdef WLAN_FEATURE_P2P_DEBUG
10764 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
10765 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
10766 {
10767 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
10768 "GO got removed");
10769 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
10770 }
10771#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010772 }
10773 EXIT();
10774 return status;
10775}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010776
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010777#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10778static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
10779 struct net_device *dev)
10780{
10781 int ret;
10782
10783 vos_ssr_protect(__func__);
10784 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
10785 vos_ssr_unprotect(__func__);
10786
10787 return ret;
10788}
10789#else
10790static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
10791 struct net_device *dev)
10792{
10793 int ret;
10794
10795 vos_ssr_protect(__func__);
10796 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
10797 vos_ssr_unprotect(__func__);
10798
10799 return ret;
10800}
10801#endif
10802
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010803#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
10804
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010805static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010806 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010807 struct cfg80211_ap_settings *params)
10808{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010809 hdd_adapter_t *pAdapter;
10810 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010811 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010812
10813 ENTER();
10814
Girish Gowlib143d7a2015-02-18 19:39:55 +053010815 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010816 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010817 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053010818 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010819 return -ENODEV;
10820 }
10821
10822 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10823 if (NULL == pAdapter)
10824 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010826 "%s: HDD adapter is Null", __func__);
10827 return -ENODEV;
10828 }
10829
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010830 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10831 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
10832 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010833 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
10834 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010836 "%s: HDD adapter magic is invalid", __func__);
10837 return -ENODEV;
10838 }
10839
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010840 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
10841
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010842 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010843 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010844 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010845 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010846 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010847 }
10848
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010849 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
10850 __func__, hdd_device_modetoString(pAdapter->device_mode),
10851 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010852
10853 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010854 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010855 )
10856 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010857 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010858
10859 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010860
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010861 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010862 {
10863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10864 FL("already beacon info added to session(%d)"),
10865 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010866 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010867 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010868
Girish Gowlib143d7a2015-02-18 19:39:55 +053010869#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10870 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10871 &new,
10872 &params->beacon);
10873#else
10874 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10875 &new,
10876 &params->beacon,
10877 params->dtim_period);
10878#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010879
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010880 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010881 {
10882 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010883 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010884 return -EINVAL;
10885 }
10886 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010887#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010888 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10889#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10890 params->channel, params->channel_type);
10891#else
10892 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10893#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010894#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010895 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010896 params->ssid_len, params->hidden_ssid,
10897 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010898 }
10899
10900 EXIT();
10901 return status;
10902}
10903
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010904static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10905 struct net_device *dev,
10906 struct cfg80211_ap_settings *params)
10907{
10908 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010909
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010910 vos_ssr_protect(__func__);
10911 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10912 vos_ssr_unprotect(__func__);
10913
10914 return ret;
10915}
10916
10917static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010918 struct net_device *dev,
10919 struct cfg80211_beacon_data *params)
10920{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010921 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010922 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010923 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010924
10925 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010926
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010927 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10928 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10929 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010930 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010931 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010932
10933 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10934 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010935 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010936 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010937 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010938 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010939
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010940 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010941 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010942 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010943 {
10944 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010945
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010946 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010947
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010948 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010949 {
10950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10951 FL("session(%d) beacon data points to NULL"),
10952 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010953 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010954 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010955
10956 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10957
10958 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010959 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010960 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010961 return -EINVAL;
10962 }
10963
10964 pAdapter->sessionCtx.ap.beacon = new;
10965
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010966 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10967 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010968 }
10969
10970 EXIT();
10971 return status;
10972}
10973
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010974static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10975 struct net_device *dev,
10976 struct cfg80211_beacon_data *params)
10977{
10978 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010979
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010980 vos_ssr_protect(__func__);
10981 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10982 vos_ssr_unprotect(__func__);
10983
10984 return ret;
10985}
10986
10987#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010988
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010989static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010990 struct net_device *dev,
10991 struct bss_parameters *params)
10992{
10993 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010994 hdd_context_t *pHddCtx;
10995 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010996
10997 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010998
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010999 if (NULL == pAdapter)
11000 {
11001 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11002 "%s: HDD adapter is Null", __func__);
11003 return -ENODEV;
11004 }
11005 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011006 ret = wlan_hdd_validate_context(pHddCtx);
11007 if (0 != ret)
11008 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011009 return ret;
11010 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011011 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11012 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
11013 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011014 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11015 __func__, hdd_device_modetoString(pAdapter->device_mode),
11016 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011017
11018 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011019 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011020 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011021 {
11022 /* ap_isolate == -1 means that in change bss, upper layer doesn't
11023 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011024 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070011025 {
11026 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011027 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011028 }
11029
11030 EXIT();
11031 return 0;
11032}
11033
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011034static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
11035 struct net_device *dev,
11036 struct bss_parameters *params)
11037{
11038 int ret;
11039
11040 vos_ssr_protect(__func__);
11041 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
11042 vos_ssr_unprotect(__func__);
11043
11044 return ret;
11045}
Kiet Lam10841362013-11-01 11:36:50 +053011046/* FUNCTION: wlan_hdd_change_country_code_cd
11047* to wait for contry code completion
11048*/
11049void* wlan_hdd_change_country_code_cb(void *pAdapter)
11050{
11051 hdd_adapter_t *call_back_pAdapter = pAdapter;
11052 complete(&call_back_pAdapter->change_country_code);
11053 return NULL;
11054}
11055
Jeff Johnson295189b2012-06-20 16:38:30 -070011056/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011057 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070011058 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
11059 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011060int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011061 struct net_device *ndev,
11062 enum nl80211_iftype type,
11063 u32 *flags,
11064 struct vif_params *params
11065 )
11066{
11067 struct wireless_dev *wdev;
11068 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011069 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070011070 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011071 tCsrRoamProfile *pRoamProfile = NULL;
11072 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011073 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011074 eMib_dot11DesiredBssType connectedBssType;
11075 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011076 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011077
11078 ENTER();
11079
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011080 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011081 {
11082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11083 "%s: Adapter context is null", __func__);
11084 return VOS_STATUS_E_FAILURE;
11085 }
11086
11087 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11088 if (!pHddCtx)
11089 {
11090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11091 "%s: HDD context is null", __func__);
11092 return VOS_STATUS_E_FAILURE;
11093 }
11094
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011095 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11096 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
11097 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011098 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011099 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011100 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011101 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011102 }
11103
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011104 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11105 __func__, hdd_device_modetoString(pAdapter->device_mode),
11106 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011107
Agarwal Ashish51325b52014-06-16 16:50:49 +053011108 if (vos_max_concurrent_connections_reached()) {
11109 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11110 return -EINVAL;
11111 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011112 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011113 wdev = ndev->ieee80211_ptr;
11114
11115#ifdef WLAN_BTAMP_FEATURE
11116 if((NL80211_IFTYPE_P2P_CLIENT == type)||
11117 (NL80211_IFTYPE_ADHOC == type)||
11118 (NL80211_IFTYPE_AP == type)||
11119 (NL80211_IFTYPE_P2P_GO == type))
11120 {
11121 pHddCtx->isAmpAllowed = VOS_FALSE;
11122 // stop AMP traffic
11123 status = WLANBAP_StopAmp();
11124 if(VOS_STATUS_SUCCESS != status )
11125 {
11126 pHddCtx->isAmpAllowed = VOS_TRUE;
11127 hddLog(VOS_TRACE_LEVEL_FATAL,
11128 "%s: Failed to stop AMP", __func__);
11129 return -EINVAL;
11130 }
11131 }
11132#endif //WLAN_BTAMP_FEATURE
11133 /* Reset the current device mode bit mask*/
11134 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
11135
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053011136 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
11137 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
11138 (type == NL80211_IFTYPE_P2P_GO)))
11139 {
11140 /* Notify Mode change in case of concurrency.
11141 * Below function invokes TDLS teardown Functionality Since TDLS is
11142 * not Supported in case of concurrency i.e Once P2P session
11143 * is detected disable offchannel and teardown TDLS links
11144 */
11145 hddLog(LOG1,
11146 FL("Device mode = %d Interface type = %d"),
11147 pAdapter->device_mode, type);
11148 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
11149 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053011150
Jeff Johnson295189b2012-06-20 16:38:30 -070011151 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011152 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070011153 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011154 )
11155 {
11156 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011157 if (!pWextState)
11158 {
11159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11160 "%s: pWextState is null", __func__);
11161 return VOS_STATUS_E_FAILURE;
11162 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011163 pRoamProfile = &pWextState->roamProfile;
11164 LastBSSType = pRoamProfile->BSSType;
11165
11166 switch (type)
11167 {
11168 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011169 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011170 hddLog(VOS_TRACE_LEVEL_INFO,
11171 "%s: setting interface Type to INFRASTRUCTURE", __func__);
11172 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011173#ifdef WLAN_FEATURE_11AC
11174 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
11175 {
11176 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
11177 }
11178#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011179 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070011180 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011181 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011182 //Check for sub-string p2p to confirm its a p2p interface
11183 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011184 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053011185#ifdef FEATURE_WLAN_TDLS
11186 mutex_lock(&pHddCtx->tdls_lock);
11187 wlan_hdd_tdls_exit(pAdapter, TRUE);
11188 mutex_unlock(&pHddCtx->tdls_lock);
11189#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011190 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11191 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11192 }
11193 else
11194 {
11195 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011196 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011197 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011198 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053011199
Jeff Johnson295189b2012-06-20 16:38:30 -070011200 case NL80211_IFTYPE_ADHOC:
11201 hddLog(VOS_TRACE_LEVEL_INFO,
11202 "%s: setting interface Type to ADHOC", __func__);
11203 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
11204 pRoamProfile->phyMode =
11205 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070011206 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011207 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053011208 hdd_set_ibss_ops( pAdapter );
11209 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053011210
11211 status = hdd_sta_id_hash_attach(pAdapter);
11212 if (VOS_STATUS_SUCCESS != status) {
11213 hddLog(VOS_TRACE_LEVEL_ERROR,
11214 FL("Failed to initialize hash for IBSS"));
11215 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011216 break;
11217
11218 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011219 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011220 {
11221 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11222 "%s: setting interface Type to %s", __func__,
11223 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
11224
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011225 //Cancel any remain on channel for GO mode
11226 if (NL80211_IFTYPE_P2P_GO == type)
11227 {
11228 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
11229 }
Mohit Khanna0f232092012-09-11 14:46:08 -070011230 if (NL80211_IFTYPE_AP == type)
11231 {
11232 /* As Loading WLAN Driver one interface being created for p2p device
11233 * address. This will take one HW STA and the max number of clients
11234 * that can connect to softAP will be reduced by one. so while changing
11235 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
11236 * interface as it is not required in SoftAP mode.
11237 */
11238
11239 // Get P2P Adapter
11240 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
11241
11242 if (pP2pAdapter)
11243 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053011244 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053011245 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070011246 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
11247 }
11248 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053011249 //Disable IMPS & BMPS for SAP/GO
11250 if(VOS_STATUS_E_FAILURE ==
11251 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
11252 {
11253 //Fail to Exit BMPS
11254 VOS_ASSERT(0);
11255 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053011256
11257 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
11258
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011259#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070011260
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011261 /* A Mutex Lock is introduced while changing the mode to
11262 * protect the concurrent access for the Adapters by TDLS
11263 * module.
11264 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011265 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011266#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011267 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053011268 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011269 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070011270 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11271 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011272#ifdef FEATURE_WLAN_TDLS
11273 mutex_unlock(&pHddCtx->tdls_lock);
11274#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011275 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
11276 (pConfig->apRandomBssidEnabled))
11277 {
11278 /* To meet Android requirements create a randomized
11279 MAC address of the form 02:1A:11:Fx:xx:xx */
11280 get_random_bytes(&ndev->dev_addr[3], 3);
11281 ndev->dev_addr[0] = 0x02;
11282 ndev->dev_addr[1] = 0x1A;
11283 ndev->dev_addr[2] = 0x11;
11284 ndev->dev_addr[3] |= 0xF0;
11285 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
11286 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080011287 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
11288 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011289 }
11290
Jeff Johnson295189b2012-06-20 16:38:30 -070011291 hdd_set_ap_ops( pAdapter->dev );
11292
Kiet Lam10841362013-11-01 11:36:50 +053011293 /* This is for only SAP mode where users can
11294 * control country through ini.
11295 * P2P GO follows station country code
11296 * acquired during the STA scanning. */
11297 if((NL80211_IFTYPE_AP == type) &&
11298 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
11299 {
11300 int status = 0;
11301 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
11302 "%s: setting country code from INI ", __func__);
11303 init_completion(&pAdapter->change_country_code);
11304 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
11305 (void *)(tSmeChangeCountryCallback)
11306 wlan_hdd_change_country_code_cb,
11307 pConfig->apCntryCode, pAdapter,
11308 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053011309 eSIR_FALSE,
11310 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053011311 if (eHAL_STATUS_SUCCESS == status)
11312 {
11313 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011314 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053011315 &pAdapter->change_country_code,
11316 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011317 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053011318 {
11319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011320 FL("SME Timed out while setting country code %ld"),
11321 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080011322
11323 if (pHddCtx->isLogpInProgress)
11324 {
11325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11326 "%s: LOGP in Progress. Ignore!!!", __func__);
11327 return -EAGAIN;
11328 }
Kiet Lam10841362013-11-01 11:36:50 +053011329 }
11330 }
11331 else
11332 {
11333 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011334 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053011335 return -EINVAL;
11336 }
11337 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011338 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070011339 if(status != VOS_STATUS_SUCCESS)
11340 {
11341 hddLog(VOS_TRACE_LEVEL_FATAL,
11342 "%s: Error initializing the ap mode", __func__);
11343 return -EINVAL;
11344 }
11345 hdd_set_conparam(1);
11346
Nirav Shah7e3c8132015-06-22 23:51:42 +053011347 status = hdd_sta_id_hash_attach(pAdapter);
11348 if (VOS_STATUS_SUCCESS != status)
11349 {
11350 hddLog(VOS_TRACE_LEVEL_ERROR,
11351 FL("Failed to initialize hash for AP"));
11352 return -EINVAL;
11353 }
11354
Jeff Johnson295189b2012-06-20 16:38:30 -070011355 /*interface type changed update in wiphy structure*/
11356 if(wdev)
11357 {
11358 wdev->iftype = type;
11359 pHddCtx->change_iface = type;
11360 }
11361 else
11362 {
11363 hddLog(VOS_TRACE_LEVEL_ERROR,
11364 "%s: ERROR !!!! Wireless dev is NULL", __func__);
11365 return -EINVAL;
11366 }
11367 goto done;
11368 }
11369
11370 default:
11371 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11372 __func__);
11373 return -EOPNOTSUPP;
11374 }
11375 }
11376 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011377 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011378 )
11379 {
11380 switch(type)
11381 {
11382 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011383 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011384 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053011385
11386 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011387#ifdef FEATURE_WLAN_TDLS
11388
11389 /* A Mutex Lock is introduced while changing the mode to
11390 * protect the concurrent access for the Adapters by TDLS
11391 * module.
11392 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011393 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011394#endif
c_hpothu002231a2015-02-05 14:58:51 +053011395 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011396 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011397 //Check for sub-string p2p to confirm its a p2p interface
11398 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011399 {
11400 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11401 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11402 }
11403 else
11404 {
11405 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011406 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011407 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053011408
11409 /* set con_mode to STA only when no SAP concurrency mode */
11410 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
11411 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070011412 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011413 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
11414 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011415#ifdef FEATURE_WLAN_TDLS
11416 mutex_unlock(&pHddCtx->tdls_lock);
11417#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053011418 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070011419 if( VOS_STATUS_SUCCESS != status )
11420 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070011421 /* In case of JB, for P2P-GO, only change interface will be called,
11422 * This is the right place to enable back bmps_imps()
11423 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011424 if (pHddCtx->hdd_wlan_suspended)
11425 {
11426 hdd_set_pwrparams(pHddCtx);
11427 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011428 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011429 goto done;
11430 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011431 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011432 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011433 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11434 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011435 goto done;
11436 default:
11437 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11438 __func__);
11439 return -EOPNOTSUPP;
11440
11441 }
11442
11443 }
11444 else
11445 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011446 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
11447 __func__, hdd_device_modetoString(pAdapter->device_mode),
11448 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011449 return -EOPNOTSUPP;
11450 }
11451
11452
11453 if(pRoamProfile)
11454 {
11455 if ( LastBSSType != pRoamProfile->BSSType )
11456 {
11457 /*interface type changed update in wiphy structure*/
11458 wdev->iftype = type;
11459
11460 /*the BSS mode changed, We need to issue disconnect
11461 if connected or in IBSS disconnect state*/
11462 if ( hdd_connGetConnectedBssType(
11463 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
11464 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
11465 {
11466 /*need to issue a disconnect to CSR.*/
11467 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11468 if( eHAL_STATUS_SUCCESS ==
11469 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11470 pAdapter->sessionId,
11471 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11472 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011473 ret = wait_for_completion_interruptible_timeout(
11474 &pAdapter->disconnect_comp_var,
11475 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11476 if (ret <= 0)
11477 {
11478 hddLog(VOS_TRACE_LEVEL_ERROR,
11479 FL("wait on disconnect_comp_var failed %ld"), ret);
11480 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011481 }
11482 }
11483 }
11484 }
11485
11486done:
11487 /*set bitmask based on updated value*/
11488 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070011489
11490 /* Only STA mode support TM now
11491 * all other mode, TM feature should be disabled */
11492 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
11493 (~VOS_STA & pHddCtx->concurrency_mode) )
11494 {
11495 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
11496 }
11497
Jeff Johnson295189b2012-06-20 16:38:30 -070011498#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011499 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011500 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070011501 {
11502 //we are ok to do AMP
11503 pHddCtx->isAmpAllowed = VOS_TRUE;
11504 }
11505#endif //WLAN_BTAMP_FEATURE
11506 EXIT();
11507 return 0;
11508}
11509
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011510/*
11511 * FUNCTION: wlan_hdd_cfg80211_change_iface
11512 * wrapper function to protect the actual implementation from SSR.
11513 */
11514int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
11515 struct net_device *ndev,
11516 enum nl80211_iftype type,
11517 u32 *flags,
11518 struct vif_params *params
11519 )
11520{
11521 int ret;
11522
11523 vos_ssr_protect(__func__);
11524 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
11525 vos_ssr_unprotect(__func__);
11526
11527 return ret;
11528}
11529
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011530#ifdef FEATURE_WLAN_TDLS
11531static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011532 struct net_device *dev,
11533#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11534 const u8 *mac,
11535#else
11536 u8 *mac,
11537#endif
11538 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011539{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011540 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011541 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011542 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011543 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011544 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011545 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011546
11547 ENTER();
11548
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011549 if (!dev) {
11550 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
11551 return -EINVAL;
11552 }
11553
11554 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11555 if (!pAdapter) {
11556 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
11557 return -EINVAL;
11558 }
11559
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011560 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011561 {
11562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11563 "Invalid arguments");
11564 return -EINVAL;
11565 }
Hoonki Lee27511902013-03-14 18:19:06 -070011566
11567 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
11568 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
11569 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070011571 "%s: TDLS mode is disabled OR not enabled in FW."
11572 MAC_ADDRESS_STR " Request declined.",
11573 __func__, MAC_ADDR_ARRAY(mac));
11574 return -ENOTSUPP;
11575 }
11576
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011577 if (pHddCtx->isLogpInProgress)
11578 {
11579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11580 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053011581 wlan_hdd_tdls_set_link_status(pAdapter,
11582 mac,
11583 eTDLS_LINK_IDLE,
11584 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011585 return -EBUSY;
11586 }
11587
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011588 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053011589 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011590
11591 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011593 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
11594 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011595 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011596 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011597 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011598
11599 /* in add station, we accept existing valid staId if there is */
11600 if ((0 == update) &&
11601 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
11602 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011603 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011604 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011605 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011606 " link_status %d. staId %d. add station ignored.",
11607 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011608 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011609 return 0;
11610 }
11611 /* in change station, we accept only when staId is valid */
11612 if ((1 == update) &&
11613 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
11614 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
11615 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011616 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011618 "%s: " MAC_ADDRESS_STR
11619 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011620 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
11621 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
11622 mutex_unlock(&pHddCtx->tdls_lock);
11623 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011624 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011625 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011626
11627 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053011628 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011629 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011630 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11631 "%s: " MAC_ADDRESS_STR
11632 " TDLS setup is ongoing. Request declined.",
11633 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070011634 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011635 }
11636
11637 /* first to check if we reached to maximum supported TDLS peer.
11638 TODO: for now, return -EPERM looks working fine,
11639 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011640 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
11641 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011642 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11644 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011645 " TDLS Max peer already connected. Request declined."
11646 " Num of peers (%d), Max allowed (%d).",
11647 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
11648 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011649 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011650 }
11651 else
11652 {
11653 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011654 mutex_lock(&pHddCtx->tdls_lock);
11655 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011656 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011657 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011658 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11660 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
11661 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011662 return -EPERM;
11663 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011664 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011665 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011666 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053011667 wlan_hdd_tdls_set_link_status(pAdapter,
11668 mac,
11669 eTDLS_LINK_CONNECTING,
11670 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011671
Jeff Johnsond75fe012013-04-06 10:53:06 -070011672 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011673 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011674 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011676 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011677 if(StaParams->htcap_present)
11678 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011680 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011682 "ht_capa->extended_capabilities: %0x",
11683 StaParams->HTCap.extendedHtCapInfo);
11684 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011686 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011688 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011689 if(StaParams->vhtcap_present)
11690 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011692 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
11693 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
11694 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
11695 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011696 {
11697 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011698 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011699 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011701 "[%d]: %x ", i, StaParams->supported_rates[i]);
11702 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070011703 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011704 else if ((1 == update) && (NULL == StaParams))
11705 {
11706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11707 "%s : update is true, but staParams is NULL. Error!", __func__);
11708 return -EPERM;
11709 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011710
11711 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
11712
11713 if (!update)
11714 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011715 /*Before adding sta make sure that device exited from BMPS*/
11716 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
11717 {
11718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11719 "%s: Adding tdls peer sta. Disable BMPS", __func__);
11720 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
11721 if (status != VOS_STATUS_SUCCESS) {
11722 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
11723 }
11724 }
11725
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011726 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011727 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011728 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011729 hddLog(VOS_TRACE_LEVEL_ERROR,
11730 FL("Failed to add TDLS peer STA. Enable Bmps"));
11731 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011732 return -EPERM;
11733 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011734 }
11735 else
11736 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011737 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011738 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011739 if (ret != eHAL_STATUS_SUCCESS) {
11740 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
11741 return -EPERM;
11742 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011743 }
11744
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011745 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011746 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
11747
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011748 mutex_lock(&pHddCtx->tdls_lock);
11749 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
11750
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011751 if ((pTdlsPeer != NULL) &&
11752 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011753 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011754 hddLog(VOS_TRACE_LEVEL_ERROR,
11755 FL("peer link status %u"), pTdlsPeer->link_status);
11756 mutex_unlock(&pHddCtx->tdls_lock);
11757 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011758 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011759 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011760
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011761 if (ret <= 0)
11762 {
11763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11764 "%s: timeout waiting for tdls add station indication %ld",
11765 __func__, ret);
11766 goto error;
11767 }
11768
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011769 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
11770 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011772 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011773 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011774 }
11775
11776 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070011777
11778error:
Atul Mittal115287b2014-07-08 13:26:33 +053011779 wlan_hdd_tdls_set_link_status(pAdapter,
11780 mac,
11781 eTDLS_LINK_IDLE,
11782 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011783 return -EPERM;
11784
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011785}
11786#endif
11787
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011788static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011789 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011790#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11791 const u8 *mac,
11792#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011793 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011794#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011795 struct station_parameters *params)
11796{
11797 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011798 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011799 hdd_context_t *pHddCtx;
11800 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011801 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011802 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011803#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011804 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011805 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011806 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011807 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011808#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011809
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011810 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011811
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011812 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011813 if ((NULL == pAdapter))
11814 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011816 "invalid adapter ");
11817 return -EINVAL;
11818 }
11819
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011820 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11821 TRACE_CODE_HDD_CHANGE_STATION,
11822 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053011823 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011824
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011825 ret = wlan_hdd_validate_context(pHddCtx);
11826 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053011827 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011828 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011829 }
11830
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011831 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11832
11833 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011834 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11836 "invalid HDD station context");
11837 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011838 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011839 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
11840
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011841 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11842 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070011843 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011844 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070011845 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011846 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070011847 WLANTL_STA_AUTHENTICATED);
11848
Gopichand Nakkala29149562013-05-10 21:43:41 +053011849 if (status != VOS_STATUS_SUCCESS)
11850 {
11851 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11852 "%s: Not able to change TL state to AUTHENTICATED", __func__);
11853 return -EINVAL;
11854 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011855 }
11856 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070011857 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
11858 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011859#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011860 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11861 StaParams.capability = params->capability;
11862 StaParams.uapsd_queues = params->uapsd_queues;
11863 StaParams.max_sp = params->max_sp;
11864
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011865 /* Convert (first channel , number of channels) tuple to
11866 * the total list of channels. This goes with the assumption
11867 * that if the first channel is < 14, then the next channels
11868 * are an incremental of 1 else an incremental of 4 till the number
11869 * of channels.
11870 */
11871 if (0 != params->supported_channels_len) {
11872 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11873 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11874 {
11875 int wifi_chan_index;
11876 StaParams.supported_channels[j] = params->supported_channels[i];
11877 wifi_chan_index =
11878 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11879 no_of_channels = params->supported_channels[i+1];
11880 for(k=1; k <= no_of_channels; k++)
11881 {
11882 StaParams.supported_channels[j+1] =
11883 StaParams.supported_channels[j] + wifi_chan_index;
11884 j+=1;
11885 }
11886 }
11887 StaParams.supported_channels_len = j;
11888 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053011889 if (params->supported_oper_classes_len >
11890 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
11891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11892 "received oper classes:%d, resetting it to max supported %d",
11893 params->supported_oper_classes_len,
11894 SIR_MAC_MAX_SUPP_OPER_CLASSES);
11895 params->supported_oper_classes_len =
11896 SIR_MAC_MAX_SUPP_OPER_CLASSES;
11897 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011898 vos_mem_copy(StaParams.supported_oper_classes,
11899 params->supported_oper_classes,
11900 params->supported_oper_classes_len);
11901 StaParams.supported_oper_classes_len =
11902 params->supported_oper_classes_len;
11903
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053011904 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
11905 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11906 "received extn capabilities:%d, resetting it to max supported",
11907 params->ext_capab_len);
11908 params->ext_capab_len = sizeof(StaParams.extn_capability);
11909 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011910 if (0 != params->ext_capab_len)
11911 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053011912 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011913
11914 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011915 {
11916 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011917 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011918 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011919
11920 StaParams.supported_rates_len = params->supported_rates_len;
11921
11922 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11923 * The supported_rates array , for all the structures propogating till Add Sta
11924 * to the firmware has to be modified , if the supplicant (ieee80211) is
11925 * modified to send more rates.
11926 */
11927
11928 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11929 */
11930 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11931 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11932
11933 if (0 != StaParams.supported_rates_len) {
11934 int i = 0;
11935 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11936 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011937 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011938 "Supported Rates with Length %d", StaParams.supported_rates_len);
11939 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011941 "[%d]: %0x", i, StaParams.supported_rates[i]);
11942 }
11943
11944 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011945 {
11946 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011947 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011948 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011949
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011950 if (0 != params->ext_capab_len ) {
11951 /*Define A Macro : TODO Sunil*/
11952 if ((1<<4) & StaParams.extn_capability[3]) {
11953 isBufSta = 1;
11954 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011955 /* TDLS Channel Switching Support */
11956 if ((1<<6) & StaParams.extn_capability[3]) {
11957 isOffChannelSupported = 1;
11958 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011959 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011960
11961 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053011962 (params->ht_capa || params->vht_capa ||
11963 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011964 /* TDLS Peer is WME/QoS capable */
11965 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011966
11967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11968 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
11969 __func__, isQosWmmSta, StaParams.htcap_present);
11970
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011971 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11972 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011973 isOffChannelSupported,
11974 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011975
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011976 if (VOS_STATUS_SUCCESS != status) {
11977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11978 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11979 return -EINVAL;
11980 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011981 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11982
11983 if (VOS_STATUS_SUCCESS != status) {
11984 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11985 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11986 return -EINVAL;
11987 }
11988 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011989#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011990 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011991 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011992 return status;
11993}
11994
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011995#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11996static int wlan_hdd_change_station(struct wiphy *wiphy,
11997 struct net_device *dev,
11998 const u8 *mac,
11999 struct station_parameters *params)
12000#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012001static int wlan_hdd_change_station(struct wiphy *wiphy,
12002 struct net_device *dev,
12003 u8 *mac,
12004 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012005#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012006{
12007 int ret;
12008
12009 vos_ssr_protect(__func__);
12010 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
12011 vos_ssr_unprotect(__func__);
12012
12013 return ret;
12014}
12015
Jeff Johnson295189b2012-06-20 16:38:30 -070012016/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012017 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012018 * This function is used to initialize the key information
12019 */
12020#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012021static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012022 struct net_device *ndev,
12023 u8 key_index, bool pairwise,
12024 const u8 *mac_addr,
12025 struct key_params *params
12026 )
12027#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012028static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012029 struct net_device *ndev,
12030 u8 key_index, const u8 *mac_addr,
12031 struct key_params *params
12032 )
12033#endif
12034{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012035 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012036 tCsrRoamSetKey setKey;
12037 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012038 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012039 v_U32_t roamId= 0xFF;
12040 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012041 hdd_hostapd_state_t *pHostapdState;
12042 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012043 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012044 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012045 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012046 v_MACADDR_t *peerMacAddr;
12047 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012048 uint8_t staid = HDD_MAX_STA_COUNT;
12049 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012050
12051 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012052
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012053 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12054 TRACE_CODE_HDD_CFG80211_ADD_KEY,
12055 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012056 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12057 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012058 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012059 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012060 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012061 }
12062
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012063 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12064 __func__, hdd_device_modetoString(pAdapter->device_mode),
12065 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012066
12067 if (CSR_MAX_NUM_KEY <= key_index)
12068 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012069 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012070 key_index);
12071
12072 return -EINVAL;
12073 }
12074
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012075 if (CSR_MAX_KEY_LEN < params->key_len)
12076 {
12077 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
12078 params->key_len);
12079
12080 return -EINVAL;
12081 }
12082
Jingxiang Gec438aea2017-10-26 16:44:00 +080012083 if (CSR_MAX_RSC_LEN < params->seq_len)
12084 {
12085 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
12086 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053012087
12088 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080012089 }
12090
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012091 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080012092 "%s: called with key index = %d & key length %d & seq length %d",
12093 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012094
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012095 peerMacAddr = (v_MACADDR_t *)mac_addr;
12096
Jeff Johnson295189b2012-06-20 16:38:30 -070012097 /*extract key idx, key len and key*/
12098 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12099 setKey.keyId = key_index;
12100 setKey.keyLength = params->key_len;
12101 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080012102 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012103
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012104 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012105 {
12106 case WLAN_CIPHER_SUITE_WEP40:
12107 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12108 break;
12109
12110 case WLAN_CIPHER_SUITE_WEP104:
12111 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
12112 break;
12113
12114 case WLAN_CIPHER_SUITE_TKIP:
12115 {
12116 u8 *pKey = &setKey.Key[0];
12117 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
12118
12119 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
12120
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012121 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070012122
12123 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012124 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012125 |--------------|----------|----------|
12126 <---16bytes---><--8bytes--><--8bytes-->
12127
12128 */
12129 /*Sme expects the 32 bytes key to be in the below order
12130
12131 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012132 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012133 |--------------|----------|----------|
12134 <---16bytes---><--8bytes--><--8bytes-->
12135 */
12136 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012137 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070012138
12139 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012140 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012141
12142 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012143 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012144
12145
12146 break;
12147 }
12148
12149 case WLAN_CIPHER_SUITE_CCMP:
12150 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
12151 break;
12152
12153#ifdef FEATURE_WLAN_WAPI
12154 case WLAN_CIPHER_SUITE_SMS4:
12155 {
12156 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12157 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
12158 params->key, params->key_len);
12159 return 0;
12160 }
12161#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012162
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012163#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012164 case WLAN_CIPHER_SUITE_KRK:
12165 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
12166 break;
12167#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012168
12169#ifdef WLAN_FEATURE_11W
12170 case WLAN_CIPHER_SUITE_AES_CMAC:
12171 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070012172 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070012173#endif
12174
Jeff Johnson295189b2012-06-20 16:38:30 -070012175 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012176 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012177 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012178 status = -EOPNOTSUPP;
12179 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012180 }
12181
12182 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
12183 __func__, setKey.encType);
12184
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012185 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070012186#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12187 (!pairwise)
12188#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012189 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070012190#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012191 )
12192 {
12193 /* set group key*/
12194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12195 "%s- %d: setting Broadcast key",
12196 __func__, __LINE__);
12197 setKey.keyDirection = eSIR_RX_ONLY;
12198 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12199 }
12200 else
12201 {
12202 /* set pairwise key*/
12203 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12204 "%s- %d: setting pairwise key",
12205 __func__, __LINE__);
12206 setKey.keyDirection = eSIR_TX_RX;
12207 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012208 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012209 }
12210 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
12211 {
12212 setKey.keyDirection = eSIR_TX_RX;
12213 /*Set the group key*/
12214 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12215 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070012216
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012217 if ( 0 != status )
12218 {
12219 hddLog(VOS_TRACE_LEVEL_ERROR,
12220 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012221 status = -EINVAL;
12222 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012223 }
12224 /*Save the keys here and call sme_RoamSetKey for setting
12225 the PTK after peer joins the IBSS network*/
12226 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
12227 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012228 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012229 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053012230 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
12231 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
12232 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012233 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012234 if( pHostapdState->bssState == BSS_START )
12235 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012236 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12237 vos_status = wlan_hdd_check_ula_done(pAdapter);
12238
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012239 if (peerMacAddr && (pairwise_set_key == true))
12240 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012241
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012242 if ( vos_status != VOS_STATUS_SUCCESS )
12243 {
12244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12245 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12246 __LINE__, vos_status );
12247
12248 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12249
12250 status = -EINVAL;
12251 goto end;
12252 }
12253
Jeff Johnson295189b2012-06-20 16:38:30 -070012254 status = WLANSAP_SetKeySta( pVosContext, &setKey);
12255
12256 if ( status != eHAL_STATUS_SUCCESS )
12257 {
12258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12259 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12260 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012261 status = -EINVAL;
12262 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012263 }
12264 }
12265
12266 /* Saving WEP keys */
12267 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
12268 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
12269 {
12270 //Save the wep key in ap context. Issue setkey after the BSS is started.
12271 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12272 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
12273 }
12274 else
12275 {
12276 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012277 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012278 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
12279 }
12280 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012281 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
12282 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012283 {
12284 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12285 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12286
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012287#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12288 if (!pairwise)
12289#else
12290 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
12291#endif
12292 {
12293 /* set group key*/
12294 if (pHddStaCtx->roam_info.deferKeyComplete)
12295 {
12296 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12297 "%s- %d: Perform Set key Complete",
12298 __func__, __LINE__);
12299 hdd_PerformRoamSetKeyComplete(pAdapter);
12300 }
12301 }
12302
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012303 if (pairwise_set_key == true)
12304 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012305
Jeff Johnson295189b2012-06-20 16:38:30 -070012306 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
12307
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080012308 pWextState->roamProfile.Keys.defaultIndex = key_index;
12309
12310
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012311 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012312 params->key, params->key_len);
12313
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012314
Jeff Johnson295189b2012-06-20 16:38:30 -070012315 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12316
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012317 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012318 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012319 __func__, setKey.peerMac[0], setKey.peerMac[1],
12320 setKey.peerMac[2], setKey.peerMac[3],
12321 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012322 setKey.keyDirection);
12323
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012324 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053012325
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012326 if ( vos_status != VOS_STATUS_SUCCESS )
12327 {
12328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012329 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12330 __LINE__, vos_status );
12331
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012332 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012333
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012334 status = -EINVAL;
12335 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012336
12337 }
12338
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012339#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012340 /* The supplicant may attempt to set the PTK once pre-authentication
12341 is done. Save the key in the UMAC and include it in the ADD BSS
12342 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012343 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012344 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012345 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012346 hddLog(VOS_TRACE_LEVEL_INFO_MED,
12347 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012348 status = 0;
12349 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012350 }
12351 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
12352 {
12353 hddLog(VOS_TRACE_LEVEL_ERROR,
12354 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012355 status = -EINVAL;
12356 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012357 }
12358#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070012359
12360 /* issue set key request to SME*/
12361 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12362 pAdapter->sessionId, &setKey, &roamId );
12363
12364 if ( 0 != status )
12365 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012366 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012367 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
12368 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012369 status = -EINVAL;
12370 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012371 }
12372
12373
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012374 /* in case of IBSS as there was no information available about WEP keys during
12375 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070012376 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012377 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
12378 !( ( IW_AUTH_KEY_MGMT_802_1X
12379 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070012380 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
12381 )
12382 &&
12383 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
12384 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
12385 )
12386 )
12387 {
12388 setKey.keyDirection = eSIR_RX_ONLY;
12389 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12390
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012391 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012392 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012393 __func__, setKey.peerMac[0], setKey.peerMac[1],
12394 setKey.peerMac[2], setKey.peerMac[3],
12395 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012396 setKey.keyDirection);
12397
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012398 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012399 pAdapter->sessionId, &setKey, &roamId );
12400
12401 if ( 0 != status )
12402 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012403 hddLog(VOS_TRACE_LEVEL_ERROR,
12404 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012405 __func__, status);
12406 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012407 status = -EINVAL;
12408 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012409 }
12410 }
12411 }
12412
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012413 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012414 for (i = 0; i < params->seq_len; i++) {
12415 rsc_counter |= (params->seq[i] << i*8);
12416 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012417 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
12418 }
12419
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012420end:
12421 /* Need to clear any trace of key value in the memory.
12422 * Thus zero out the memory even though it is local
12423 * variable.
12424 */
12425 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012426 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012427 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012428}
12429
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012430#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12431static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12432 struct net_device *ndev,
12433 u8 key_index, bool pairwise,
12434 const u8 *mac_addr,
12435 struct key_params *params
12436 )
12437#else
12438static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12439 struct net_device *ndev,
12440 u8 key_index, const u8 *mac_addr,
12441 struct key_params *params
12442 )
12443#endif
12444{
12445 int ret;
12446 vos_ssr_protect(__func__);
12447#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12448 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
12449 mac_addr, params);
12450#else
12451 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
12452 params);
12453#endif
12454 vos_ssr_unprotect(__func__);
12455
12456 return ret;
12457}
12458
Jeff Johnson295189b2012-06-20 16:38:30 -070012459/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012460 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012461 * This function is used to get the key information
12462 */
12463#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012464static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012465 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012466 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012467 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012468 const u8 *mac_addr, void *cookie,
12469 void (*callback)(void *cookie, struct key_params*)
12470 )
12471#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012472static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012473 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012474 struct net_device *ndev,
12475 u8 key_index, const u8 *mac_addr, void *cookie,
12476 void (*callback)(void *cookie, struct key_params*)
12477 )
12478#endif
12479{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012480 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012481 hdd_wext_state_t *pWextState = NULL;
12482 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012483 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012484 hdd_context_t *pHddCtx;
12485 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012486
12487 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012488
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012489 if (NULL == pAdapter)
12490 {
12491 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12492 "%s: HDD adapter is Null", __func__);
12493 return -ENODEV;
12494 }
12495
12496 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12497 ret = wlan_hdd_validate_context(pHddCtx);
12498 if (0 != ret)
12499 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012500 return ret;
12501 }
12502
12503 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12504 pRoamProfile = &(pWextState->roamProfile);
12505
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012506 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12507 __func__, hdd_device_modetoString(pAdapter->device_mode),
12508 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012509
Jeff Johnson295189b2012-06-20 16:38:30 -070012510 memset(&params, 0, sizeof(params));
12511
12512 if (CSR_MAX_NUM_KEY <= key_index)
12513 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012514 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012515 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012516 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012517
12518 switch(pRoamProfile->EncryptionType.encryptionType[0])
12519 {
12520 case eCSR_ENCRYPT_TYPE_NONE:
12521 params.cipher = IW_AUTH_CIPHER_NONE;
12522 break;
12523
12524 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
12525 case eCSR_ENCRYPT_TYPE_WEP40:
12526 params.cipher = WLAN_CIPHER_SUITE_WEP40;
12527 break;
12528
12529 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
12530 case eCSR_ENCRYPT_TYPE_WEP104:
12531 params.cipher = WLAN_CIPHER_SUITE_WEP104;
12532 break;
12533
12534 case eCSR_ENCRYPT_TYPE_TKIP:
12535 params.cipher = WLAN_CIPHER_SUITE_TKIP;
12536 break;
12537
12538 case eCSR_ENCRYPT_TYPE_AES:
12539 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
12540 break;
12541
12542 default:
12543 params.cipher = IW_AUTH_CIPHER_NONE;
12544 break;
12545 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012546
c_hpothuaaf19692014-05-17 17:01:48 +053012547 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12548 TRACE_CODE_HDD_CFG80211_GET_KEY,
12549 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012550
Jeff Johnson295189b2012-06-20 16:38:30 -070012551 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
12552 params.seq_len = 0;
12553 params.seq = NULL;
12554 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
12555 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012556 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012557 return 0;
12558}
12559
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012560#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12561static int wlan_hdd_cfg80211_get_key(
12562 struct wiphy *wiphy,
12563 struct net_device *ndev,
12564 u8 key_index, bool pairwise,
12565 const u8 *mac_addr, void *cookie,
12566 void (*callback)(void *cookie, struct key_params*)
12567 )
12568#else
12569static int wlan_hdd_cfg80211_get_key(
12570 struct wiphy *wiphy,
12571 struct net_device *ndev,
12572 u8 key_index, const u8 *mac_addr, void *cookie,
12573 void (*callback)(void *cookie, struct key_params*)
12574 )
12575#endif
12576{
12577 int ret;
12578
12579 vos_ssr_protect(__func__);
12580#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12581 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
12582 mac_addr, cookie, callback);
12583#else
12584 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
12585 callback);
12586#endif
12587 vos_ssr_unprotect(__func__);
12588
12589 return ret;
12590}
12591
Jeff Johnson295189b2012-06-20 16:38:30 -070012592/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012593 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012594 * This function is used to delete the key information
12595 */
12596#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012597static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012598 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012599 u8 key_index,
12600 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012601 const u8 *mac_addr
12602 )
12603#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012604static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012605 struct net_device *ndev,
12606 u8 key_index,
12607 const u8 *mac_addr
12608 )
12609#endif
12610{
12611 int status = 0;
12612
12613 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012614 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070012615 //it is observed that this is invalidating peer
12616 //key index whenever re-key is done. This is affecting data link.
12617 //It should be ok to ignore del_key.
12618#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012619 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
12620 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012621 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12622 tCsrRoamSetKey setKey;
12623 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012624
Jeff Johnson295189b2012-06-20 16:38:30 -070012625 ENTER();
12626
12627 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
12628 __func__,pAdapter->device_mode);
12629
12630 if (CSR_MAX_NUM_KEY <= key_index)
12631 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012632 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012633 key_index);
12634
12635 return -EINVAL;
12636 }
12637
12638 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12639 setKey.keyId = key_index;
12640
12641 if (mac_addr)
12642 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
12643 else
12644 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
12645
12646 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
12647
12648 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012649 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012650 )
12651 {
12652
12653 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070012654 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
12655 if( pHostapdState->bssState == BSS_START)
12656 {
12657 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012658
Jeff Johnson295189b2012-06-20 16:38:30 -070012659 if ( status != eHAL_STATUS_SUCCESS )
12660 {
12661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12662 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12663 __LINE__, status );
12664 }
12665 }
12666 }
12667 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012668 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070012669 )
12670 {
12671 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12672
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012673 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12674
12675 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012676 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012677 __func__, setKey.peerMac[0], setKey.peerMac[1],
12678 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070012679 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012680 if(pAdapter->sessionCtx.station.conn_info.connState ==
12681 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070012682 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012683 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012684 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012685
Jeff Johnson295189b2012-06-20 16:38:30 -070012686 if ( 0 != status )
12687 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012688 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012689 "%s: sme_RoamSetKey failure, returned %d",
12690 __func__, status);
12691 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12692 return -EINVAL;
12693 }
12694 }
12695 }
12696#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012697 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012698 return status;
12699}
12700
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012701#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12702static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12703 struct net_device *ndev,
12704 u8 key_index,
12705 bool pairwise,
12706 const u8 *mac_addr
12707 )
12708#else
12709static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12710 struct net_device *ndev,
12711 u8 key_index,
12712 const u8 *mac_addr
12713 )
12714#endif
12715{
12716 int ret;
12717
12718 vos_ssr_protect(__func__);
12719#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12720 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
12721 mac_addr);
12722#else
12723 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
12724#endif
12725 vos_ssr_unprotect(__func__);
12726
12727 return ret;
12728}
12729
Jeff Johnson295189b2012-06-20 16:38:30 -070012730/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012731 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012732 * This function is used to set the default tx key index
12733 */
12734#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012735static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012736 struct net_device *ndev,
12737 u8 key_index,
12738 bool unicast, bool multicast)
12739#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012740static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012741 struct net_device *ndev,
12742 u8 key_index)
12743#endif
12744{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012745 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012746 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012747 hdd_wext_state_t *pWextState;
12748 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012749 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012750
12751 ENTER();
12752
Gopichand Nakkala29149562013-05-10 21:43:41 +053012753 if ((NULL == pAdapter))
12754 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012756 "invalid adapter");
12757 return -EINVAL;
12758 }
12759
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012760 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12761 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
12762 pAdapter->sessionId, key_index));
12763
Gopichand Nakkala29149562013-05-10 21:43:41 +053012764 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12765 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12766
12767 if ((NULL == pWextState) || (NULL == pHddStaCtx))
12768 {
12769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12770 "invalid Wext state or HDD context");
12771 return -EINVAL;
12772 }
12773
Arif Hussain6d2a3322013-11-17 19:50:10 -080012774 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012775 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012776
Jeff Johnson295189b2012-06-20 16:38:30 -070012777 if (CSR_MAX_NUM_KEY <= key_index)
12778 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012779 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012780 key_index);
12781
12782 return -EINVAL;
12783 }
12784
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012785 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12786 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012787 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012788 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012789 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012790 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012791
Jeff Johnson295189b2012-06-20 16:38:30 -070012792 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012793 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012794 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012795 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012796 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080012797 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080012798#ifdef FEATURE_WLAN_WAPI
12799 (eCSR_ENCRYPT_TYPE_WPI !=
12800 pHddStaCtx->conn_info.ucEncryptionType) &&
12801#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012802 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080012803 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070012804 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012805 {
12806 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070012807 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012808
Jeff Johnson295189b2012-06-20 16:38:30 -070012809 tCsrRoamSetKey setKey;
12810 v_U32_t roamId= 0xFF;
12811 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012812
12813 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012814 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012815
Jeff Johnson295189b2012-06-20 16:38:30 -070012816 Keys->defaultIndex = (u8)key_index;
12817 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12818 setKey.keyId = key_index;
12819 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012820
12821 vos_mem_copy(&setKey.Key[0],
12822 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012823 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012824
Gopichand Nakkala29149562013-05-10 21:43:41 +053012825 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012826
12827 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070012828 &pHddStaCtx->conn_info.bssId[0],
12829 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012830
Gopichand Nakkala29149562013-05-10 21:43:41 +053012831 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
12832 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
12833 eCSR_ENCRYPT_TYPE_WEP104)
12834 {
12835 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
12836 even though ap is configured for WEP-40 encryption. In this canse the key length
12837 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
12838 type(104) and switching encryption type to 40*/
12839 pWextState->roamProfile.EncryptionType.encryptionType[0] =
12840 eCSR_ENCRYPT_TYPE_WEP40;
12841 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
12842 eCSR_ENCRYPT_TYPE_WEP40;
12843 }
12844
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012845 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012846 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012847
Jeff Johnson295189b2012-06-20 16:38:30 -070012848 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012849 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012850 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012851
Jeff Johnson295189b2012-06-20 16:38:30 -070012852 if ( 0 != status )
12853 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012854 hddLog(VOS_TRACE_LEVEL_ERROR,
12855 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012856 status);
12857 return -EINVAL;
12858 }
12859 }
12860 }
12861
12862 /* In SoftAp mode setting key direction for default mode */
12863 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
12864 {
12865 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
12866 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
12867 (eCSR_ENCRYPT_TYPE_AES !=
12868 pWextState->roamProfile.EncryptionType.encryptionType[0])
12869 )
12870 {
12871 /* Saving key direction for default key index to TX default */
12872 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12873 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
12874 }
12875 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012876 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012877 return status;
12878}
12879
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012880#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12881static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12882 struct net_device *ndev,
12883 u8 key_index,
12884 bool unicast, bool multicast)
12885#else
12886static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12887 struct net_device *ndev,
12888 u8 key_index)
12889#endif
12890{
12891 int ret;
12892 vos_ssr_protect(__func__);
12893#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12894 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
12895 multicast);
12896#else
12897 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
12898#endif
12899 vos_ssr_unprotect(__func__);
12900
12901 return ret;
12902}
12903
Jeff Johnson295189b2012-06-20 16:38:30 -070012904/*
12905 * FUNCTION: wlan_hdd_cfg80211_inform_bss
12906 * This function is used to inform the BSS details to nl80211 interface.
12907 */
12908static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
12909 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
12910{
12911 struct net_device *dev = pAdapter->dev;
12912 struct wireless_dev *wdev = dev->ieee80211_ptr;
12913 struct wiphy *wiphy = wdev->wiphy;
12914 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12915 int chan_no;
12916 int ie_length;
12917 const char *ie;
12918 unsigned int freq;
12919 struct ieee80211_channel *chan;
12920 int rssi = 0;
12921 struct cfg80211_bss *bss = NULL;
12922
Jeff Johnson295189b2012-06-20 16:38:30 -070012923 if( NULL == pBssDesc )
12924 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012925 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012926 return bss;
12927 }
12928
12929 chan_no = pBssDesc->channelId;
12930 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12931 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12932
12933 if( NULL == ie )
12934 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012935 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012936 return bss;
12937 }
12938
12939#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12940 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12941 {
12942 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12943 }
12944 else
12945 {
12946 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12947 }
12948#else
12949 freq = ieee80211_channel_to_frequency(chan_no);
12950#endif
12951
12952 chan = __ieee80211_get_channel(wiphy, freq);
12953
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012954 if (!chan) {
12955 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12956 return NULL;
12957 }
12958
Abhishek Singhaee43942014-06-16 18:55:47 +053012959 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012960
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012961 return cfg80211_inform_bss(wiphy, chan,
12962#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12963 CFG80211_BSS_FTYPE_UNKNOWN,
12964#endif
12965 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012966 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012967 pBssDesc->capabilityInfo,
12968 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012969 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012970}
12971
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012972/*
12973 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
12974 * interface that BSS might have been lost.
12975 * @pAdapter: adaptor
12976 * @bssid: bssid which might have been lost
12977 *
12978 * Return: bss which is unlinked from kernel cache
12979 */
12980struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
12981 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
12982{
12983 struct net_device *dev = pAdapter->dev;
12984 struct wireless_dev *wdev = dev->ieee80211_ptr;
12985 struct wiphy *wiphy = wdev->wiphy;
12986 struct cfg80211_bss *bss = NULL;
12987
Abhishek Singh5a597e62016-12-05 15:16:30 +053012988 bss = hdd_get_bss_entry(wiphy,
12989 NULL, bssid,
12990 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012991 if (bss == NULL) {
12992 hddLog(LOGE, FL("BSS not present"));
12993 } else {
12994 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
12995 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
12996 cfg80211_unlink_bss(wiphy, bss);
12997 }
12998 return bss;
12999}
Jeff Johnson295189b2012-06-20 16:38:30 -070013000
13001
13002/*
13003 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
13004 * This function is used to inform the BSS details to nl80211 interface.
13005 */
13006struct cfg80211_bss*
13007wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
13008 tSirBssDescription *bss_desc
13009 )
13010{
13011 /*
13012 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
13013 already exists in bss data base of cfg80211 for that particular BSS ID.
13014 Using cfg80211_inform_bss_frame to update the bss entry instead of
13015 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
13016 now there is no possibility to get the mgmt(probe response) frame from PE,
13017 converting bss_desc to ieee80211_mgmt(probe response) and passing to
13018 cfg80211_inform_bss_frame.
13019 */
13020 struct net_device *dev = pAdapter->dev;
13021 struct wireless_dev *wdev = dev->ieee80211_ptr;
13022 struct wiphy *wiphy = wdev->wiphy;
13023 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013024#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13025 qcom_ie_age *qie_age = NULL;
13026 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
13027#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013028 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013029#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013030 const char *ie =
13031 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
13032 unsigned int freq;
13033 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013034 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013035 struct cfg80211_bss *bss_status = NULL;
13036 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
13037 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070013038 hdd_context_t *pHddCtx;
13039 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070013040#ifdef WLAN_OPEN_SOURCE
13041 struct timespec ts;
13042#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013043
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013044
Wilson Yangf80a0542013-10-07 13:02:37 -070013045 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13046 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070013047 if (0 != status)
13048 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013049 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013050 }
13051
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013052 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070013053 if (!mgmt)
13054 {
13055 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13056 "%s: memory allocation failed ", __func__);
13057 return NULL;
13058 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013059
Jeff Johnson295189b2012-06-20 16:38:30 -070013060 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013061
13062#ifdef WLAN_OPEN_SOURCE
13063 /* Android does not want the timestamp from the frame.
13064 Instead it wants a monotonic increasing value */
13065 get_monotonic_boottime(&ts);
13066 mgmt->u.probe_resp.timestamp =
13067 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
13068#else
13069 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070013070 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
13071 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070013072
13073#endif
13074
Jeff Johnson295189b2012-06-20 16:38:30 -070013075 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
13076 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013077
13078#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13079 /* GPS Requirement: need age ie per entry. Using vendor specific. */
13080 /* Assuming this is the last IE, copy at the end */
13081 ie_length -=sizeof(qcom_ie_age);
13082 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
13083 qie_age->element_id = QCOM_VENDOR_IE_ID;
13084 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
13085 qie_age->oui_1 = QCOM_OUI1;
13086 qie_age->oui_2 = QCOM_OUI2;
13087 qie_age->oui_3 = QCOM_OUI3;
13088 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053013089 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
13090 * bss related timestamp is in units of ms. Due to this when scan results
13091 * are sent to lowi the scan age is high.To address this, send age in units
13092 * of 1/10 ms.
13093 */
13094 qie_age->age = (vos_timer_get_system_time() -
13095 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013096#endif
13097
Jeff Johnson295189b2012-06-20 16:38:30 -070013098 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053013099 if (bss_desc->fProbeRsp)
13100 {
13101 mgmt->frame_control |=
13102 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
13103 }
13104 else
13105 {
13106 mgmt->frame_control |=
13107 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
13108 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013109
13110#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013111 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013112 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
13113 {
13114 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
13115 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013116 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013117 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
13118
13119 {
13120 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
13121 }
13122 else
13123 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013124 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
13125 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070013126 kfree(mgmt);
13127 return NULL;
13128 }
13129#else
13130 freq = ieee80211_channel_to_frequency(chan_no);
13131#endif
13132 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013133 /*when the band is changed on the fly using the GUI, three things are done
13134 * 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)
13135 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
13136 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
13137 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
13138 * and discards the channels correponding to previous band and calls back with zero bss results.
13139 * 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
13140 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
13141 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
13142 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
13143 * So drop the bss and continue to next bss.
13144 */
13145 if(chan == NULL)
13146 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053013147 hddLog(VOS_TRACE_LEVEL_ERROR,
13148 FL("chan pointer is NULL, chan_no: %d freq: %d"),
13149 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070013150 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013151 return NULL;
13152 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053013153 /*To keep the rssi icon of the connected AP in the scan window
13154 *and the rssi icon of the wireless networks in sync
13155 * */
13156 if (( eConnectionState_Associated ==
13157 pAdapter->sessionCtx.station.conn_info.connState ) &&
13158 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
13159 pAdapter->sessionCtx.station.conn_info.bssId,
13160 WNI_CFG_BSSID_LEN)) &&
13161 (pHddCtx->hdd_wlan_suspended == FALSE))
13162 {
13163 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
13164 rssi = (pAdapter->rssi * 100);
13165 }
13166 else
13167 {
13168 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
13169 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013170
Nirav Shah20ac06f2013-12-12 18:14:06 +053013171 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053013172 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
13173 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053013174
Jeff Johnson295189b2012-06-20 16:38:30 -070013175 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
13176 frame_len, rssi, GFP_KERNEL);
13177 kfree(mgmt);
13178 return bss_status;
13179}
13180
13181/*
13182 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
13183 * This function is used to update the BSS data base of CFG8011
13184 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013185struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013186 tCsrRoamInfo *pRoamInfo
13187 )
13188{
13189 tCsrRoamConnectedProfile roamProfile;
13190 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13191 struct cfg80211_bss *bss = NULL;
13192
13193 ENTER();
13194
13195 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
13196 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
13197
13198 if (NULL != roamProfile.pBssDesc)
13199 {
Girish Gowlif4b68022014-08-28 23:18:57 +053013200 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13201 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070013202
13203 if (NULL == bss)
13204 {
13205 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
13206 __func__);
13207 }
13208
13209 sme_RoamFreeConnectProfile(hHal, &roamProfile);
13210 }
13211 else
13212 {
13213 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
13214 __func__);
13215 }
13216 return bss;
13217}
13218
13219/*
13220 * FUNCTION: wlan_hdd_cfg80211_update_bss
13221 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013222static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
13223 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070013224 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013225{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013226 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013227 tCsrScanResultInfo *pScanResult;
13228 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013229 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013230 tScanResultHandle pResult;
13231 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013232 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013233 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013234 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013235
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013236 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13237 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
13238 NO_SESSION, pAdapter->sessionId));
13239
Wilson Yangf80a0542013-10-07 13:02:37 -070013240 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013241 ret = wlan_hdd_validate_context(pHddCtx);
13242 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070013243 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013244 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070013245 }
13246
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013247 if (pAdapter->request != NULL)
13248 {
13249 if ((pAdapter->request->n_ssids == 1)
13250 && (pAdapter->request->ssids != NULL)
13251 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
13252 is_p2p_scan = true;
13253 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013254 /*
13255 * start getting scan results and populate cgf80211 BSS database
13256 */
13257 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
13258
13259 /* no scan results */
13260 if (NULL == pResult)
13261 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013262 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
13263 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013264 wlan_hdd_get_frame_logs(pAdapter,
13265 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070013266 return status;
13267 }
13268
13269 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
13270
13271 while (pScanResult)
13272 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013273 /*
13274 * cfg80211_inform_bss() is not updating ie field of bss entry, if
13275 * entry already exists in bss data base of cfg80211 for that
13276 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
13277 * bss entry instead of cfg80211_inform_bss, But this call expects
13278 * mgmt packet as input. As of now there is no possibility to get
13279 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070013280 * ieee80211_mgmt(probe response) and passing to c
13281 * fg80211_inform_bss_frame.
13282 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013283 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
13284 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
13285 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013286 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13287 continue; //Skip the non p2p bss entries
13288 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013289 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13290 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013291
Jeff Johnson295189b2012-06-20 16:38:30 -070013292
13293 if (NULL == bss_status)
13294 {
13295 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013296 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013297 }
13298 else
13299 {
Yue Maf49ba872013-08-19 12:04:25 -070013300 cfg80211_put_bss(
13301#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
13302 wiphy,
13303#endif
13304 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070013305 }
13306
13307 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13308 }
13309
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013310 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013311 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013312 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013313}
13314
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013315void
13316hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
13317{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013318 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080013319 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013320} /****** end hddPrintMacAddr() ******/
13321
13322void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013323hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013324{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013325 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013326 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013327 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
13328 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
13329 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013330} /****** end hddPrintPmkId() ******/
13331
13332//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
13333//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
13334
13335//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
13336//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
13337
13338#define dump_bssid(bssid) \
13339 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013340 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
13341 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013342 }
13343
13344#define dump_pmkid(pMac, pmkid) \
13345 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013346 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
13347 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013348 }
13349
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070013350#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013351/*
13352 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
13353 * This function is used to notify the supplicant of a new PMKSA candidate.
13354 */
13355int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013356 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013357 int index, bool preauth )
13358{
Jeff Johnsone7245742012-09-05 17:12:55 -070013359#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013360 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013361 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013362
13363 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070013364 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013365
13366 if( NULL == pRoamInfo )
13367 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013368 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013369 return -EINVAL;
13370 }
13371
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013372 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
13373 {
13374 dump_bssid(pRoamInfo->bssid);
13375 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013376 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013377 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013378#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013379 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013380}
13381#endif //FEATURE_WLAN_LFR
13382
Yue Maef608272013-04-08 23:09:17 -070013383#ifdef FEATURE_WLAN_LFR_METRICS
13384/*
13385 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
13386 * 802.11r/LFR metrics reporting function to report preauth initiation
13387 *
13388 */
13389#define MAX_LFR_METRICS_EVENT_LENGTH 100
13390VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
13391 tCsrRoamInfo *pRoamInfo)
13392{
13393 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13394 union iwreq_data wrqu;
13395
13396 ENTER();
13397
13398 if (NULL == pAdapter)
13399 {
13400 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13401 return VOS_STATUS_E_FAILURE;
13402 }
13403
13404 /* create the event */
13405 memset(&wrqu, 0, sizeof(wrqu));
13406 memset(metrics_notification, 0, sizeof(metrics_notification));
13407
13408 wrqu.data.pointer = metrics_notification;
13409 wrqu.data.length = scnprintf(metrics_notification,
13410 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
13411 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13412
13413 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13414
13415 EXIT();
13416
13417 return VOS_STATUS_SUCCESS;
13418}
13419
13420/*
13421 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
13422 * 802.11r/LFR metrics reporting function to report preauth completion
13423 * or failure
13424 */
13425VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
13426 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
13427{
13428 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13429 union iwreq_data wrqu;
13430
13431 ENTER();
13432
13433 if (NULL == pAdapter)
13434 {
13435 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13436 return VOS_STATUS_E_FAILURE;
13437 }
13438
13439 /* create the event */
13440 memset(&wrqu, 0, sizeof(wrqu));
13441 memset(metrics_notification, 0, sizeof(metrics_notification));
13442
13443 scnprintf(metrics_notification, sizeof(metrics_notification),
13444 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
13445 MAC_ADDR_ARRAY(pRoamInfo->bssid));
13446
13447 if (1 == preauth_status)
13448 strncat(metrics_notification, " TRUE", 5);
13449 else
13450 strncat(metrics_notification, " FALSE", 6);
13451
13452 wrqu.data.pointer = metrics_notification;
13453 wrqu.data.length = strlen(metrics_notification);
13454
13455 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13456
13457 EXIT();
13458
13459 return VOS_STATUS_SUCCESS;
13460}
13461
13462/*
13463 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
13464 * 802.11r/LFR metrics reporting function to report handover initiation
13465 *
13466 */
13467VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
13468 tCsrRoamInfo *pRoamInfo)
13469{
13470 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13471 union iwreq_data wrqu;
13472
13473 ENTER();
13474
13475 if (NULL == pAdapter)
13476 {
13477 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13478 return VOS_STATUS_E_FAILURE;
13479 }
13480
13481 /* create the event */
13482 memset(&wrqu, 0, sizeof(wrqu));
13483 memset(metrics_notification, 0, sizeof(metrics_notification));
13484
13485 wrqu.data.pointer = metrics_notification;
13486 wrqu.data.length = scnprintf(metrics_notification,
13487 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
13488 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13489
13490 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13491
13492 EXIT();
13493
13494 return VOS_STATUS_SUCCESS;
13495}
13496#endif
13497
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013498
13499/**
13500 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
13501 * @scan_req: scan request to be checked
13502 *
13503 * Return: true or false
13504 */
13505#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
13506static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13507 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013508 *scan_req, hdd_context_t
13509 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013510{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013511 if (!scan_req || !scan_req->wiphy ||
13512 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013513 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13514 return false;
13515 }
13516 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
13517 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
13518 return false;
13519 }
13520 return true;
13521}
13522#else
13523static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13524 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013525 *scan_req, hdd_context_t
13526 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013527{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013528 if (!scan_req || !scan_req->wiphy ||
13529 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013530 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13531 return false;
13532 }
13533 return true;
13534}
13535#endif
13536
Mukul Sharmab392b642017-08-17 17:45:29 +053013537#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013538/*
13539 * FUNCTION: hdd_cfg80211_scan_done_callback
13540 * scanning callback function, called after finishing scan
13541 *
13542 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013543static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070013544 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
13545{
13546 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013547 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013548 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013549 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013550 struct cfg80211_scan_request *req = NULL;
13551 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013552 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013553 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013554 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013555 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013556
13557 ENTER();
13558
c_manjee1b4ab9a2016-10-26 11:36:55 +053013559 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
13560 !pAdapter->dev) {
13561 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
13562 return 0;
13563 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013564 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053013565 if (NULL == pHddCtx) {
13566 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013567 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013568 }
13569
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013570#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053013571 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013572 {
13573 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013574 }
13575#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013576 pScanInfo = &pHddCtx->scan_info;
13577
Jeff Johnson295189b2012-06-20 16:38:30 -070013578 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070013579 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080013580 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013581 __func__, halHandle, pContext, (int) scanId, (int) status);
13582
Kiet Lamac06e2c2013-10-23 16:25:07 +053013583 pScanInfo->mScanPendingCounter = 0;
13584
Jeff Johnson295189b2012-06-20 16:38:30 -070013585 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013586 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070013587 &pScanInfo->scan_req_completion_event,
13588 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013589 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070013590 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013591 hddLog(VOS_TRACE_LEVEL_ERROR,
13592 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070013593 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013594 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013595 }
13596
Yue Maef608272013-04-08 23:09:17 -070013597 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070013598 {
13599 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013600 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013601 }
13602
13603 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013604 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070013605 {
13606 hddLog(VOS_TRACE_LEVEL_INFO,
13607 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080013608 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070013609 (int) scanId);
13610 }
13611
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013612#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053013613 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013614#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013615 {
13616 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
13617 pAdapter);
13618 if (0 > ret)
13619 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013620 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013621
Jeff Johnson295189b2012-06-20 16:38:30 -070013622 /* If any client wait scan result through WEXT
13623 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013624 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070013625 {
13626 /* The other scan request waiting for current scan finish
13627 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013628 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013629 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013630 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070013631 }
13632 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013633 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013634 {
13635 struct net_device *dev = pAdapter->dev;
13636 union iwreq_data wrqu;
13637 int we_event;
13638 char *msg;
13639
13640 memset(&wrqu, '\0', sizeof(wrqu));
13641 we_event = SIOCGIWSCAN;
13642 msg = NULL;
13643 wireless_send_event(dev, we_event, &wrqu, msg);
13644 }
13645 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013646 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013647
13648 /* Get the Scan Req */
13649 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053013650 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013651
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013652 /* Scan is no longer pending */
13653 pScanInfo->mScanPending = VOS_FALSE;
13654
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013655 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070013656 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013657#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13658 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053013659 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013660#endif
13661
13662 if (pAdapter->dev) {
13663 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
13664 pAdapter->dev->name);
13665 }
mukul sharmae7041822015-12-03 15:09:21 +053013666 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070013667 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013668 }
13669
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013670 /* last_scan_timestamp is used to decide if new scan
13671 * is needed or not on station interface. If last station
13672 * scan time and new station scan time is less then
13673 * last_scan_timestamp ; driver will return cached scan.
13674 */
13675 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
13676 {
13677 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
13678
13679 if ( req->n_channels )
13680 {
13681 for (i = 0; i < req->n_channels ; i++ )
13682 {
13683 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
13684 }
13685 /* store no of channel scanned */
13686 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
13687 }
13688
13689 }
13690
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070013691 /*
13692 * cfg80211_scan_done informing NL80211 about completion
13693 * of scanning
13694 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013695 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
13696 {
13697 aborted = true;
13698 }
mukul sharmae7041822015-12-03 15:09:21 +053013699
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013700#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053013701 if (NET_DEV_IS_IFF_UP(pAdapter) &&
13702 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013703#endif
13704 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053013705
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013706 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070013707
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013708allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013709 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
13710 ) && (pHddCtx->spoofMacAddr.isEnabled
13711 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053013712 /* Generate new random mac addr for next scan */
13713 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053013714
13715 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
13716 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053013717 }
13718
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013719 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013720 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013721
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013722 /* Acquire wakelock to handle the case where APP's tries to suspend
13723 * immediatly after the driver gets connect request(i.e after scan)
13724 * from supplicant, this result in app's is suspending and not able
13725 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013726 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013727
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013728#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053013729 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013730#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013731#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013732 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013733#endif
13734
Jeff Johnson295189b2012-06-20 16:38:30 -070013735 EXIT();
13736 return 0;
13737}
13738
13739/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053013740 * FUNCTION: hdd_isConnectionInProgress
13741 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013742 *
13743 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013744v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
13745 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013746{
13747 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13748 hdd_station_ctx_t *pHddStaCtx = NULL;
13749 hdd_adapter_t *pAdapter = NULL;
13750 VOS_STATUS status = 0;
13751 v_U8_t staId = 0;
13752 v_U8_t *staMac = NULL;
13753
13754 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13755
13756 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13757 {
13758 pAdapter = pAdapterNode->pAdapter;
13759
13760 if( pAdapter )
13761 {
13762 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013763 "%s: Adapter with device mode %s (%d) exists",
13764 __func__, hdd_device_modetoString(pAdapter->device_mode),
13765 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013766 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053013767 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13768 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
13769 (eConnectionState_Connecting ==
13770 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13771 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053013772 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070013773 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053013774 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013775 if (session_id && reason)
13776 {
13777 *session_id = pAdapter->sessionId;
13778 *reason = eHDD_CONNECTION_IN_PROGRESS;
13779 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013780 return VOS_TRUE;
13781 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013782 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053013783 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013784 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053013785 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070013786 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013787 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013788 if (session_id && reason)
13789 {
13790 *session_id = pAdapter->sessionId;
13791 *reason = eHDD_REASSOC_IN_PROGRESS;
13792 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013793 return VOS_TRUE;
13794 }
13795 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013796 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13797 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013798 {
13799 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13800 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013801 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013802 {
13803 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053013804 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080013805 "%s: client " MAC_ADDRESS_STR
13806 " is in the middle of WPS/EAPOL exchange.", __func__,
13807 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013808 if (session_id && reason)
13809 {
13810 *session_id = pAdapter->sessionId;
13811 *reason = eHDD_EAPOL_IN_PROGRESS;
13812 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013813 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013814 }
13815 }
13816 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
13817 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
13818 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013819 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13820 ptSapContext pSapCtx = NULL;
13821 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13822 if(pSapCtx == NULL){
13823 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13824 FL("psapCtx is NULL"));
13825 return VOS_FALSE;
13826 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013827 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
13828 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013829 if ((pSapCtx->aStaInfo[staId].isUsed) &&
13830 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013831 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013832 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013833
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053013834 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080013835 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
13836 "middle of WPS/EAPOL exchange.", __func__,
13837 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013838 if (session_id && reason)
13839 {
13840 *session_id = pAdapter->sessionId;
13841 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
13842 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013843 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013844 }
13845 }
13846 }
13847 }
13848 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13849 pAdapterNode = pNext;
13850 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013851 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013852}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013853
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013854/**
13855 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
13856 * to the Scan request
13857 * @scanRequest: Pointer to the csr scan request
13858 * @request: Pointer to the scan request from supplicant
13859 *
13860 * Return: None
13861 */
13862#ifdef CFG80211_SCAN_BSSID
13863static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13864 struct cfg80211_scan_request *request)
13865{
13866 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
13867}
13868#else
13869static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13870 struct cfg80211_scan_request *request)
13871{
13872}
13873#endif
13874
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013875/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013876 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070013877 * this scan respond to scan trigger and update cfg80211 scan database
13878 * later, scan dump command can be used to recieve scan results
13879 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013880int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013881#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13882 struct net_device *dev,
13883#endif
13884 struct cfg80211_scan_request *request)
13885{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013886 hdd_adapter_t *pAdapter = NULL;
13887 hdd_context_t *pHddCtx = NULL;
13888 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013889 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013890 tCsrScanRequest scanRequest;
13891 tANI_U8 *channelList = NULL, i;
13892 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013893 int status;
13894 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013895 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013896 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053013897 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013898 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013899 v_U8_t curr_session_id;
13900 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070013901
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013902#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
13903 struct net_device *dev = NULL;
13904 if (NULL == request)
13905 {
13906 hddLog(VOS_TRACE_LEVEL_ERROR,
13907 "%s: scan req param null", __func__);
13908 return -EINVAL;
13909 }
13910 dev = request->wdev->netdev;
13911#endif
13912
13913 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13914 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
13915 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13916
Jeff Johnson295189b2012-06-20 16:38:30 -070013917 ENTER();
13918
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013919 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13920 __func__, hdd_device_modetoString(pAdapter->device_mode),
13921 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013922
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013923 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013924 if (0 != status)
13925 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013926 return status;
13927 }
13928
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013929 if (NULL == pwextBuf)
13930 {
13931 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
13932 __func__);
13933 return -EIO;
13934 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013935 cfg_param = pHddCtx->cfg_ini;
13936 pScanInfo = &pHddCtx->scan_info;
13937
Jeff Johnson295189b2012-06-20 16:38:30 -070013938#ifdef WLAN_BTAMP_FEATURE
13939 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013940 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070013941 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013942 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013943 "%s: No scanning when AMP is on", __func__);
13944 return -EOPNOTSUPP;
13945 }
13946#endif
13947 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013948 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013949 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013950 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013951 "%s: Not scanning on device_mode = %s (%d)",
13952 __func__, hdd_device_modetoString(pAdapter->device_mode),
13953 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013954 return -EOPNOTSUPP;
13955 }
13956
13957 if (TRUE == pScanInfo->mScanPending)
13958 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013959 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
13960 {
13961 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
13962 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013963 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013964 }
13965
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053013966 // Don't allow scan if PNO scan is going on.
13967 if (pHddCtx->isPnoEnable)
13968 {
13969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13970 FL("pno scan in progress"));
13971 return -EBUSY;
13972 }
13973
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013974 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070013975 //Channel and action frame is pending
13976 //Otherwise Cancel Remain On Channel and allow Scan
13977 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013978 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070013979 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013980 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070013981 return -EBUSY;
13982 }
13983
Jeff Johnson295189b2012-06-20 16:38:30 -070013984 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
13985 {
13986 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080013987 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013988 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013989 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013990 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
13991 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013992 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013993 "%s: MAX TM Level Scan not allowed", __func__);
13994 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013995 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013996 }
13997 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
13998
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013999 /* Check if scan is allowed at this point of time.
14000 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053014001 if (TRUE == pHddCtx->btCoexModeSet)
14002 {
14003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14004 FL("BTCoex Mode operation in progress"));
14005 return -EBUSY;
14006 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014007 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014008 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014009
14010 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
14011 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
14012 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014013 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
14014 pHddCtx->last_scan_reject_reason != curr_reason ||
14015 !pHddCtx->last_scan_reject_timestamp)
14016 {
14017 pHddCtx->last_scan_reject_session_id = curr_session_id;
14018 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053014019 pHddCtx->last_scan_reject_timestamp =
14020 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014021 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053014022 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053014023 else
14024 {
14025 pHddCtx->scan_reject_cnt++;
14026
Abhishek Singhe4b12562017-06-20 16:53:39 +053014027 if ((pHddCtx->scan_reject_cnt >=
14028 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053014029 vos_system_time_after(jiffies_to_msecs(jiffies),
14030 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014031 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014032 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
14033 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
14034 vos_system_time_after(jiffies_to_msecs(jiffies),
14035 pHddCtx->last_scan_reject_timestamp));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014036 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014037 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014038 if (pHddCtx->cfg_ini->enableFatalEvent)
14039 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
14040 WLAN_LOG_INDICATOR_HOST_DRIVER,
14041 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
14042 FALSE, FALSE);
14043 else
14044 {
14045 hddLog(LOGE, FL("Triggering SSR"));
14046 vos_wlanRestart();
14047 }
14048 }
14049 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014050 return -EBUSY;
14051 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014052 pHddCtx->last_scan_reject_timestamp = 0;
14053 pHddCtx->last_scan_reject_session_id = 0xFF;
14054 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014055 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014056
Jeff Johnson295189b2012-06-20 16:38:30 -070014057 vos_mem_zero( &scanRequest, sizeof(scanRequest));
14058
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014059 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
14060 * Becasue of this, driver is assuming that this is not wildcard scan and so
14061 * is not aging out the scan results.
14062 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053014063 if ((request->ssids) && (request->n_ssids == 1) &&
14064 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014065 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014066 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014067
14068 if ((request->ssids) && (0 < request->n_ssids))
14069 {
14070 tCsrSSIDInfo *SsidInfo;
14071 int j;
14072 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
14073 /* Allocate num_ssid tCsrSSIDInfo structure */
14074 SsidInfo = scanRequest.SSIDs.SSIDList =
14075 ( tCsrSSIDInfo *)vos_mem_malloc(
14076 request->n_ssids*sizeof(tCsrSSIDInfo));
14077
14078 if(NULL == scanRequest.SSIDs.SSIDList)
14079 {
14080 hddLog(VOS_TRACE_LEVEL_ERROR,
14081 "%s: memory alloc failed SSIDInfo buffer", __func__);
14082 return -ENOMEM;
14083 }
14084
14085 /* copy all the ssid's and their length */
14086 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
14087 {
14088 /* get the ssid length */
14089 SsidInfo->SSID.length = request->ssids[j].ssid_len;
14090 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
14091 SsidInfo->SSID.length);
14092 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
14093 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
14094 j, SsidInfo->SSID.ssId);
14095 }
14096 /* set the scan type to active */
14097 scanRequest.scanType = eSIR_ACTIVE_SCAN;
14098 }
14099 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014100 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014101 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14102 TRACE_CODE_HDD_CFG80211_SCAN,
14103 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070014104 /* set the scan type to active */
14105 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070014106 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014107 else
14108 {
14109 /*Set the scan type to default type, in this case it is ACTIVE*/
14110 scanRequest.scanType = pScanInfo->scan_mode;
14111 }
14112 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
14113 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070014114
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014115 csr_scan_request_assign_bssid(&scanRequest, request);
14116
Jeff Johnson295189b2012-06-20 16:38:30 -070014117 /* set BSSType to default type */
14118 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
14119
14120 /*TODO: scan the requested channels only*/
14121
14122 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014123 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070014124 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014125 hddLog(VOS_TRACE_LEVEL_WARN,
14126 "No of Scan Channels exceeded limit: %d", request->n_channels);
14127 request->n_channels = MAX_CHANNEL;
14128 }
14129
14130 hddLog(VOS_TRACE_LEVEL_INFO,
14131 "No of Scan Channels: %d", request->n_channels);
14132
14133
14134 if( request->n_channels )
14135 {
14136 char chList [(request->n_channels*5)+1];
14137 int len;
14138 channelList = vos_mem_malloc( request->n_channels );
14139 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053014140 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014141 hddLog(VOS_TRACE_LEVEL_ERROR,
14142 "%s: memory alloc failed channelList", __func__);
14143 status = -ENOMEM;
14144 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053014145 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014146
14147 for( i = 0, len = 0; i < request->n_channels ; i++ )
14148 {
14149 channelList[i] = request->channels[i]->hw_value;
14150 len += snprintf(chList+len, 5, "%d ", channelList[i]);
14151 }
14152
Nirav Shah20ac06f2013-12-12 18:14:06 +053014153 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014154 "Channel-List: %s ", chList);
14155 }
c_hpothu53512302014-04-15 18:49:53 +053014156
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014157 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
14158 scanRequest.ChannelInfo.ChannelList = channelList;
14159
14160 /* set requestType to full scan */
14161 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
14162
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014163 /* if there is back to back scan happening in driver with in
14164 * nDeferScanTimeInterval interval driver should defer new scan request
14165 * and should provide last cached scan results instead of new channel list.
14166 * This rule is not applicable if scan is p2p scan.
14167 * This condition will work only in case when last request no of channels
14168 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053014169 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053014170 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014171 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014172
Sushant Kaushik86592172015-04-27 16:35:03 +053014173 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
14174 /* if wps ie is NULL , then only defer scan */
14175 if ( pWpsIe == NULL &&
14176 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053014177 {
14178 if ( pScanInfo->last_scan_timestamp !=0 &&
14179 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
14180 {
14181 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
14182 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
14183 vos_mem_compare(pScanInfo->last_scan_channelList,
14184 channelList, pScanInfo->last_scan_numChannels))
14185 {
14186 hddLog(VOS_TRACE_LEVEL_WARN,
14187 " New and old station scan time differ is less then %u",
14188 pHddCtx->cfg_ini->nDeferScanTimeInterval);
14189
14190 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014191 pAdapter);
14192
Agarwal Ashish57e84372014-12-05 18:26:53 +053014193 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014194 "Return old cached scan as all channels and no of channels are same");
14195
Agarwal Ashish57e84372014-12-05 18:26:53 +053014196 if (0 > ret)
14197 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014198
Agarwal Ashish57e84372014-12-05 18:26:53 +053014199 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014200
14201 status = eHAL_STATUS_SUCCESS;
14202 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053014203 }
14204 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014205 }
14206
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014207 /* Flush the scan results(only p2p beacons) for STA scan and P2P
14208 * search (Flush on both full scan and social scan but not on single
14209 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
14210 */
14211
14212 /* Supplicant does single channel scan after 8-way handshake
14213 * and in that case driver shoudnt flush scan results. If
14214 * driver flushes the scan results here and unfortunately if
14215 * the AP doesnt respond to our probe req then association
14216 * fails which is not desired
14217 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014218 if ((request->n_ssids == 1)
14219 && (request->ssids != NULL)
14220 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
14221 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014222
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014223 if( is_p2p_scan ||
14224 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014225 {
14226 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
14227 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
14228 pAdapter->sessionId );
14229 }
14230
14231 if( request->ie_len )
14232 {
14233 /* save this for future association (join requires this) */
14234 /*TODO: Array needs to be converted to dynamic allocation,
14235 * as multiple ie.s can be sent in cfg80211_scan_request structure
14236 * CR 597966
14237 */
14238 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
14239 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
14240 pScanInfo->scanAddIE.length = request->ie_len;
14241
14242 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14243 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14244 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014245 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014246 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070014247 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014248 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
14249 memcpy( pwextBuf->roamProfile.addIEScan,
14250 request->ie, request->ie_len);
14251 }
14252 else
14253 {
14254 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
14255 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070014256 }
14257
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014258 }
14259 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
14260 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
14261
14262 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
14263 request->ie_len);
14264 if (pP2pIe != NULL)
14265 {
14266#ifdef WLAN_FEATURE_P2P_DEBUG
14267 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
14268 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
14269 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053014270 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014271 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
14272 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14273 "Go nego completed to Connection is started");
14274 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14275 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053014276 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014277 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
14278 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014279 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014280 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
14281 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14282 "Disconnected state to Connection is started");
14283 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14284 "for 4way Handshake");
14285 }
14286#endif
14287
14288 /* no_cck will be set during p2p find to disable 11b rates */
14289 if(TRUE == request->no_cck)
14290 {
14291 hddLog(VOS_TRACE_LEVEL_INFO,
14292 "%s: This is a P2P Search", __func__);
14293 scanRequest.p2pSearch = 1;
14294
14295 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053014296 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014297 /* set requestType to P2P Discovery */
14298 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
14299 }
14300
14301 /*
14302 Skip Dfs Channel in case of P2P Search
14303 if it is set in ini file
14304 */
14305 if(cfg_param->skipDfsChnlInP2pSearch)
14306 {
14307 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014308 }
14309 else
14310 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014311 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014312 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014313
Agarwal Ashish4f616132013-12-30 23:32:50 +053014314 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014315 }
14316 }
14317
14318 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
14319
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014320#ifdef FEATURE_WLAN_TDLS
14321 /* if tdls disagree scan right now, return immediately.
14322 tdls will schedule the scan when scan is allowed. (return SUCCESS)
14323 or will reject the scan if any TDLS is in progress. (return -EBUSY)
14324 */
14325 status = wlan_hdd_tdls_scan_callback (pAdapter,
14326 wiphy,
14327#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14328 dev,
14329#endif
14330 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014331 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014332 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053014333 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014334 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
14335 "scan rejected %d", __func__, status);
14336 else
14337 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
14338 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014339 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053014340 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014341 }
14342#endif
14343
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014344 /* acquire the wakelock to avoid the apps suspend during the scan. To
14345 * address the following issues.
14346 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
14347 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
14348 * for long time, this result in apps running at full power for long time.
14349 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
14350 * be stuck in full power because of resume BMPS
14351 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014352 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014353
Nirav Shah20ac06f2013-12-12 18:14:06 +053014354 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
14355 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014356 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
14357 scanRequest.requestType, scanRequest.scanType,
14358 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053014359 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
14360
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014361 if (pHddCtx->spoofMacAddr.isEnabled &&
14362 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053014363 {
14364 hddLog(VOS_TRACE_LEVEL_INFO,
14365 "%s: MAC Spoofing enabled for current scan", __func__);
14366 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14367 * to fill TxBds for probe request during current scan
14368 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014369 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053014370 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014371
14372 if(status != VOS_STATUS_SUCCESS)
14373 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014374 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014375 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053014376#ifdef FEATURE_WLAN_TDLS
14377 wlan_hdd_tdls_scan_done_callback(pAdapter);
14378#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014379 goto free_mem;
14380 }
Siddharth Bhal76972212014-10-15 16:22:51 +053014381 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014382 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070014383 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014384 pAdapter->sessionId, &scanRequest, &scanId,
14385 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070014386
Jeff Johnson295189b2012-06-20 16:38:30 -070014387 if (eHAL_STATUS_SUCCESS != status)
14388 {
14389 hddLog(VOS_TRACE_LEVEL_ERROR,
14390 "%s: sme_ScanRequest returned error %d", __func__, status);
14391 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014392 if(eHAL_STATUS_RESOURCES == status)
14393 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014394 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
14395 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014396 status = -EBUSY;
14397 } else {
14398 status = -EIO;
14399 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014400 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014401
14402#ifdef FEATURE_WLAN_TDLS
14403 wlan_hdd_tdls_scan_done_callback(pAdapter);
14404#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014405 goto free_mem;
14406 }
14407
14408 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014409 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070014410 pAdapter->request = request;
14411 pScanInfo->scanId = scanId;
14412
14413 complete(&pScanInfo->scan_req_completion_event);
14414
14415free_mem:
14416 if( scanRequest.SSIDs.SSIDList )
14417 {
14418 vos_mem_free(scanRequest.SSIDs.SSIDList);
14419 }
14420
14421 if( channelList )
14422 vos_mem_free( channelList );
14423
14424 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014425 return status;
14426}
14427
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014428int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
14429#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14430 struct net_device *dev,
14431#endif
14432 struct cfg80211_scan_request *request)
14433{
14434 int ret;
14435
14436 vos_ssr_protect(__func__);
14437 ret = __wlan_hdd_cfg80211_scan(wiphy,
14438#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14439 dev,
14440#endif
14441 request);
14442 vos_ssr_unprotect(__func__);
14443
14444 return ret;
14445}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014446
14447void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
14448{
14449 v_U8_t iniDot11Mode =
14450 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
14451 eHddDot11Mode hddDot11Mode = iniDot11Mode;
14452
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014453 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
14454 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014455 switch ( iniDot11Mode )
14456 {
14457 case eHDD_DOT11_MODE_AUTO:
14458 case eHDD_DOT11_MODE_11ac:
14459 case eHDD_DOT11_MODE_11ac_ONLY:
14460#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053014461 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
14462 sme_IsFeatureSupportedByFW(DOT11AC) )
14463 hddDot11Mode = eHDD_DOT11_MODE_11ac;
14464 else
14465 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014466#else
14467 hddDot11Mode = eHDD_DOT11_MODE_11n;
14468#endif
14469 break;
14470 case eHDD_DOT11_MODE_11n:
14471 case eHDD_DOT11_MODE_11n_ONLY:
14472 hddDot11Mode = eHDD_DOT11_MODE_11n;
14473 break;
14474 default:
14475 hddDot11Mode = iniDot11Mode;
14476 break;
14477 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014478#ifdef WLAN_FEATURE_AP_HT40_24G
14479 if (operationChannel > SIR_11B_CHANNEL_END)
14480#endif
14481 {
14482 /* This call decides required channel bonding mode */
14483 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014484 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053014485 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014486 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014487}
14488
Jeff Johnson295189b2012-06-20 16:38:30 -070014489/*
14490 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014491 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014492 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014493int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014494 const u8 *ssid, size_t ssid_len, const u8 *bssid,
14495 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070014496{
14497 int status = 0;
14498 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080014499 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053014500 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014501 v_U32_t roamId;
14502 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070014503 eCsrAuthType RSNAuthType;
14504
14505 ENTER();
14506
14507 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080014508 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053014509 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080014510
14511 status = wlan_hdd_validate_context(pHddCtx);
14512 if (status)
14513 {
Yue Mae36e3552014-03-05 17:06:20 -080014514 return status;
14515 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014516
Jeff Johnson295189b2012-06-20 16:38:30 -070014517 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
14518 {
14519 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
14520 return -EINVAL;
14521 }
14522
Nitesh Shah9b066282017-06-06 18:05:52 +053014523 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
14524
Jeff Johnson295189b2012-06-20 16:38:30 -070014525 pRoamProfile = &pWextState->roamProfile;
14526
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014527 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070014528 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014529 hdd_station_ctx_t *pHddStaCtx;
14530 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053014531 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014532
Siddharth Bhalda0d1622015-04-24 15:47:49 +053014533 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
14534
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014535 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070014536 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
14537 {
14538 /*QoS not enabled in cfg file*/
14539 pRoamProfile->uapsd_mask = 0;
14540 }
14541 else
14542 {
14543 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014544 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070014545 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
14546 }
14547
14548 pRoamProfile->SSIDs.numOfSSIDs = 1;
14549 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
14550 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014551 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070014552 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
14553 ssid, ssid_len);
14554
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014555 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
14556 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
14557
Jeff Johnson295189b2012-06-20 16:38:30 -070014558 if (bssid)
14559 {
14560 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014561 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014562 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014563 /* Save BSSID in seperate variable as well, as RoamProfile
14564 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070014565 case of join failure we should send valid BSSID to supplicant
14566 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014567 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014568 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014569
Jeff Johnson295189b2012-06-20 16:38:30 -070014570 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014571 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070014572 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014573 /* Store bssid_hint to use in the scan filter. */
14574 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
14575 WNI_CFG_BSSID_LEN);
14576 /*
14577 * Save BSSID in seperate variable as well, as RoamProfile
14578 * BSSID is getting zeroed out in the association process. And in
14579 * case of join failure we should send valid BSSID to supplicant
14580 */
14581 vos_mem_copy(pWextState->req_bssId, bssid_hint,
14582 WNI_CFG_BSSID_LEN);
14583 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
14584 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070014585 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014586
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014587
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014588 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
14589 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014590 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
14591 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014592 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014593 /*set gen ie*/
14594 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
14595 /*set auth*/
14596 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
14597 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014598#ifdef FEATURE_WLAN_WAPI
14599 if (pAdapter->wapi_info.nWapiMode)
14600 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014601 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014602 switch (pAdapter->wapi_info.wapiAuthMode)
14603 {
14604 case WAPI_AUTH_MODE_PSK:
14605 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014606 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014607 pAdapter->wapi_info.wapiAuthMode);
14608 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
14609 break;
14610 }
14611 case WAPI_AUTH_MODE_CERT:
14612 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014613 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014614 pAdapter->wapi_info.wapiAuthMode);
14615 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
14616 break;
14617 }
14618 } // End of switch
14619 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
14620 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
14621 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014622 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014623 pRoamProfile->AuthType.numEntries = 1;
14624 pRoamProfile->EncryptionType.numEntries = 1;
14625 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14626 pRoamProfile->mcEncryptionType.numEntries = 1;
14627 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14628 }
14629 }
14630#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014631#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014632 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014633 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14634 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
14635 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014636 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
14637 sizeof (tSirGtkOffloadParams));
14638 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014639 }
14640#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014641 pRoamProfile->csrPersona = pAdapter->device_mode;
14642
Jeff Johnson32d95a32012-09-10 13:15:23 -070014643 if( operatingChannel )
14644 {
14645 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
14646 pRoamProfile->ChannelInfo.numOfChannels = 1;
14647 }
Chet Lanctot186b5732013-03-18 10:26:30 -070014648 else
14649 {
14650 pRoamProfile->ChannelInfo.ChannelList = NULL;
14651 pRoamProfile->ChannelInfo.numOfChannels = 0;
14652 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014653 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
14654 {
14655 hdd_select_cbmode(pAdapter,operatingChannel);
14656 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014657
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014658 /*
14659 * Change conn_state to connecting before sme_RoamConnect(),
14660 * because sme_RoamConnect() has a direct path to call
14661 * hdd_smeRoamCallback(), which will change the conn_state
14662 * If direct path, conn_state will be accordingly changed
14663 * to NotConnected or Associated by either
14664 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
14665 * in sme_RoamCallback()
14666 * if sme_RomConnect is to be queued,
14667 * Connecting state will remain until it is completed.
14668 * If connection state is not changed,
14669 * connection state will remain in eConnectionState_NotConnected state.
14670 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
14671 * if conn state is eConnectionState_NotConnected.
14672 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
14673 * informed of connect result indication which is an issue.
14674 */
14675
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014676 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14677 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053014678 {
14679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014680 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014681 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
14682 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053014683 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014684 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014685 pAdapter->sessionId, pRoamProfile, &roamId);
14686
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014687 if ((eHAL_STATUS_SUCCESS != status) &&
14688 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14689 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014690
14691 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014692 hddLog(VOS_TRACE_LEVEL_ERROR,
14693 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
14694 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014695 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014696 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014697 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014698 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014699
14700 pRoamProfile->ChannelInfo.ChannelList = NULL;
14701 pRoamProfile->ChannelInfo.numOfChannels = 0;
14702
Jeff Johnson295189b2012-06-20 16:38:30 -070014703 }
14704 else
14705 {
14706 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
14707 return -EINVAL;
14708 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080014709 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014710 return status;
14711}
14712
14713/*
14714 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
14715 * This function is used to set the authentication type (OPEN/SHARED).
14716 *
14717 */
14718static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
14719 enum nl80211_auth_type auth_type)
14720{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014721 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014722 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14723
14724 ENTER();
14725
14726 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014727 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070014728 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014729 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014730 hddLog(VOS_TRACE_LEVEL_INFO,
14731 "%s: set authentication type to AUTOSWITCH", __func__);
14732 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
14733 break;
14734
14735 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014736#ifdef WLAN_FEATURE_VOWIFI_11R
14737 case NL80211_AUTHTYPE_FT:
14738#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014739 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014740 "%s: set authentication type to OPEN", __func__);
14741 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
14742 break;
14743
14744 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014745 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014746 "%s: set authentication type to SHARED", __func__);
14747 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
14748 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014749#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014750 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014751 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014752 "%s: set authentication type to CCKM WPA", __func__);
14753 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
14754 break;
14755#endif
14756
14757
14758 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014759 hddLog(VOS_TRACE_LEVEL_ERROR,
14760 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014761 auth_type);
14762 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
14763 return -EINVAL;
14764 }
14765
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014766 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014767 pHddStaCtx->conn_info.authType;
14768 return 0;
14769}
14770
14771/*
14772 * FUNCTION: wlan_hdd_set_akm_suite
14773 * This function is used to set the key mgmt type(PSK/8021x).
14774 *
14775 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014776static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014777 u32 key_mgmt
14778 )
14779{
14780 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14781 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053014782 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014783#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053014784#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014785#endif
14786#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053014787#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014788#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014789 /*set key mgmt type*/
14790 switch(key_mgmt)
14791 {
14792 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053014793 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014794#ifdef WLAN_FEATURE_VOWIFI_11R
14795 case WLAN_AKM_SUITE_FT_PSK:
14796#endif
14797 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070014798 __func__);
14799 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
14800 break;
14801
14802 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053014803 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014804#ifdef WLAN_FEATURE_VOWIFI_11R
14805 case WLAN_AKM_SUITE_FT_8021X:
14806#endif
14807 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070014808 __func__);
14809 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14810 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014811#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014812#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
14813#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
14814 case WLAN_AKM_SUITE_CCKM:
14815 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
14816 __func__);
14817 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
14818 break;
14819#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070014820#ifndef WLAN_AKM_SUITE_OSEN
14821#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
14822 case WLAN_AKM_SUITE_OSEN:
14823 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
14824 __func__);
14825 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14826 break;
14827#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014828
14829 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014830 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014831 __func__, key_mgmt);
14832 return -EINVAL;
14833
14834 }
14835 return 0;
14836}
14837
14838/*
14839 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014840 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070014841 * (NONE/WEP40/WEP104/TKIP/CCMP).
14842 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014843static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
14844 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070014845 bool ucast
14846 )
14847{
14848 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014849 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014850 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14851
14852 ENTER();
14853
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014854 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014855 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014856 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070014857 __func__, cipher);
14858 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14859 }
14860 else
14861 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014862
Jeff Johnson295189b2012-06-20 16:38:30 -070014863 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014864 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014865 {
14866 case IW_AUTH_CIPHER_NONE:
14867 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14868 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014869
Jeff Johnson295189b2012-06-20 16:38:30 -070014870 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014871 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070014872 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014873
Jeff Johnson295189b2012-06-20 16:38:30 -070014874 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014875 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070014876 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014877
Jeff Johnson295189b2012-06-20 16:38:30 -070014878 case WLAN_CIPHER_SUITE_TKIP:
14879 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
14880 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014881
Jeff Johnson295189b2012-06-20 16:38:30 -070014882 case WLAN_CIPHER_SUITE_CCMP:
14883 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14884 break;
14885#ifdef FEATURE_WLAN_WAPI
14886 case WLAN_CIPHER_SUITE_SMS4:
14887 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
14888 break;
14889#endif
14890
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014891#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014892 case WLAN_CIPHER_SUITE_KRK:
14893 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
14894 break;
14895#endif
14896 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014897 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014898 __func__, cipher);
14899 return -EOPNOTSUPP;
14900 }
14901 }
14902
14903 if (ucast)
14904 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014905 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014906 __func__, encryptionType);
14907 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14908 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014909 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014910 encryptionType;
14911 }
14912 else
14913 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014914 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014915 __func__, encryptionType);
14916 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
14917 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
14918 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
14919 }
14920
14921 return 0;
14922}
14923
14924
14925/*
14926 * FUNCTION: wlan_hdd_cfg80211_set_ie
14927 * This function is used to parse WPA/RSN IE's.
14928 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014929int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014930#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14931 const u8 *ie,
14932#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014933 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014934#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014935 size_t ie_len
14936 )
14937{
14938 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014939#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14940 const u8 *genie = ie;
14941#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014942 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014943#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014944 v_U16_t remLen = ie_len;
14945#ifdef FEATURE_WLAN_WAPI
14946 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
14947 u16 *tmp;
14948 v_U16_t akmsuiteCount;
14949 int *akmlist;
14950#endif
14951 ENTER();
14952
14953 /* clear previous assocAddIE */
14954 pWextState->assocAddIE.length = 0;
14955 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014956 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014957
14958 while (remLen >= 2)
14959 {
14960 v_U16_t eLen = 0;
14961 v_U8_t elementId;
14962 elementId = *genie++;
14963 eLen = *genie++;
14964 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014965
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053014966 /* Sanity check on eLen */
14967 if (eLen > remLen) {
14968 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
14969 __func__, eLen, elementId);
14970 VOS_ASSERT(0);
14971 return -EINVAL;
14972 }
14973
Arif Hussain6d2a3322013-11-17 19:50:10 -080014974 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070014975 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014976
14977 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070014978 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014979 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014980 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 -070014981 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014982 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014983 "%s: Invalid WPA IE", __func__);
14984 return -EINVAL;
14985 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014986 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070014987 {
14988 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014989 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014990 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014991
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014992 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014993 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014994 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
14995 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014996 VOS_ASSERT(0);
14997 return -ENOMEM;
14998 }
14999 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15000 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15001 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015002
Jeff Johnson295189b2012-06-20 16:38:30 -070015003 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
15004 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15005 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15006 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015007 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
15008 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053015009 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
15010 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
15011 __func__, eLen);
15012 VOS_ASSERT(0);
15013 return -EINVAL;
15014 }
15015
Jeff Johnson295189b2012-06-20 16:38:30 -070015016 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
15017 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15018 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
15019 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
15020 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
15021 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015022 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053015023 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070015024 {
15025 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015026 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015027 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015028
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015029 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015030 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015031 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15032 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015033 VOS_ASSERT(0);
15034 return -ENOMEM;
15035 }
15036 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15037 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15038 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015039
Jeff Johnson295189b2012-06-20 16:38:30 -070015040 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15041 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15042 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015043#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015044 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
15045 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015046 /*Consider WFD IE, only for P2P Client */
15047 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15048 {
15049 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015050 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015051 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015052
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015053 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015054 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015055 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15056 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015057 VOS_ASSERT(0);
15058 return -ENOMEM;
15059 }
15060 // WFD IE is saved to Additional IE ; it should be accumulated to handle
15061 // WPS IE + P2P IE + WFD IE
15062 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15063 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015064
Jeff Johnson295189b2012-06-20 16:38:30 -070015065 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15066 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15067 }
15068#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015069 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015070 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015071 HS20_OUI_TYPE_SIZE)) )
15072 {
15073 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015074 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015075 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015076
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015077 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015078 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015079 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15080 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015081 VOS_ASSERT(0);
15082 return -ENOMEM;
15083 }
15084 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15085 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015086
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015087 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15088 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15089 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015090 /* Appending OSEN Information Element in Assiciation Request */
15091 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
15092 OSEN_OUI_TYPE_SIZE)) )
15093 {
15094 v_U16_t curAddIELen = pWextState->assocAddIE.length;
15095 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
15096 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015097
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015098 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015099 {
15100 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15101 "Need bigger buffer space");
15102 VOS_ASSERT(0);
15103 return -ENOMEM;
15104 }
15105 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15106 pWextState->assocAddIE.length += eLen + 2;
15107
15108 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
15109 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15110 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15111 }
15112
Abhishek Singh4322e622015-06-10 15:42:54 +053015113 /* Update only for WPA IE */
15114 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
15115 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015116
15117 /* populating as ADDIE in beacon frames */
15118 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015119 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015120 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
15121 {
15122 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15123 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
15124 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15125 {
15126 hddLog(LOGE,
15127 "Coldn't pass "
15128 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
15129 }
15130 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
15131 else
15132 hddLog(LOGE,
15133 "Could not pass on "
15134 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
15135
15136 /* IBSS mode doesn't contain params->proberesp_ies still
15137 beaconIE's need to be populated in probe response frames */
15138 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
15139 {
15140 u16 rem_probe_resp_ie_len = eLen + 2;
15141 u8 probe_rsp_ie_len[3] = {0};
15142 u8 counter = 0;
15143
15144 /* Check Probe Resp Length if it is greater then 255 then
15145 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
15146 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
15147 not able Store More then 255 bytes into One Variable */
15148
15149 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
15150 {
15151 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
15152 {
15153 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
15154 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
15155 }
15156 else
15157 {
15158 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
15159 rem_probe_resp_ie_len = 0;
15160 }
15161 }
15162
15163 rem_probe_resp_ie_len = 0;
15164
15165 if (probe_rsp_ie_len[0] > 0)
15166 {
15167 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15168 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
15169 (tANI_U8*)(genie - 2),
15170 probe_rsp_ie_len[0], NULL,
15171 eANI_BOOLEAN_FALSE)
15172 == eHAL_STATUS_FAILURE)
15173 {
15174 hddLog(LOGE,
15175 "Could not pass"
15176 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
15177 }
15178 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
15179 }
15180
15181 if (probe_rsp_ie_len[1] > 0)
15182 {
15183 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15184 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
15185 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15186 probe_rsp_ie_len[1], NULL,
15187 eANI_BOOLEAN_FALSE)
15188 == eHAL_STATUS_FAILURE)
15189 {
15190 hddLog(LOGE,
15191 "Could not pass"
15192 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
15193 }
15194 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
15195 }
15196
15197 if (probe_rsp_ie_len[2] > 0)
15198 {
15199 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15200 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
15201 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15202 probe_rsp_ie_len[2], NULL,
15203 eANI_BOOLEAN_FALSE)
15204 == eHAL_STATUS_FAILURE)
15205 {
15206 hddLog(LOGE,
15207 "Could not pass"
15208 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
15209 }
15210 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
15211 }
15212
15213 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15214 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
15215 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15216 {
15217 hddLog(LOGE,
15218 "Could not pass"
15219 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
15220 }
15221 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015222 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070015223 break;
15224 case DOT11F_EID_RSN:
15225 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
15226 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15227 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
15228 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
15229 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
15230 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053015231
Abhishek Singhb16f3562016-01-20 11:08:32 +053015232 /* Appending extended capabilities with Interworking or
15233 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053015234 *
15235 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053015236 * interworkingService or bsstransition bit is set to 1.
15237 * Driver is only interested in interworkingService and
15238 * bsstransition capability from supplicant.
15239 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053015240 * required from supplicat, it needs to be handled while
15241 * sending Assoc Req in LIM.
15242 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015243 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015244 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015245 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015246 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015247 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015248
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015249 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015250 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015251 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15252 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015253 VOS_ASSERT(0);
15254 return -ENOMEM;
15255 }
15256 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15257 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015258
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015259 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15260 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15261 break;
15262 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015263#ifdef FEATURE_WLAN_WAPI
15264 case WLAN_EID_WAPI:
15265 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015266 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070015267 pAdapter->wapi_info.nWapiMode);
15268 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015269 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070015270 akmsuiteCount = WPA_GET_LE16(tmp);
15271 tmp = tmp + 1;
15272 akmlist = (int *)(tmp);
15273 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
15274 {
15275 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
15276 }
15277 else
15278 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015279 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070015280 VOS_ASSERT(0);
15281 return -EINVAL;
15282 }
15283
15284 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
15285 {
15286 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015287 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015288 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015289 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015290 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015291 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015292 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015293 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015294 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
15295 }
15296 break;
15297#endif
15298 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015299 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015300 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015301 /* when Unknown IE is received we should break and continue
15302 * to the next IE in the buffer instead we were returning
15303 * so changing this to break */
15304 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015305 }
15306 genie += eLen;
15307 remLen -= eLen;
15308 }
15309 EXIT();
15310 return 0;
15311}
15312
15313/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015314 * FUNCTION: hdd_isWPAIEPresent
15315 * Parse the received IE to find the WPA IE
15316 *
15317 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015318static bool hdd_isWPAIEPresent(
15319#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
15320 const u8 *ie,
15321#else
15322 u8 *ie,
15323#endif
15324 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015325{
15326 v_U8_t eLen = 0;
15327 v_U16_t remLen = ie_len;
15328 v_U8_t elementId = 0;
15329
15330 while (remLen >= 2)
15331 {
15332 elementId = *ie++;
15333 eLen = *ie++;
15334 remLen -= 2;
15335 if (eLen > remLen)
15336 {
15337 hddLog(VOS_TRACE_LEVEL_ERROR,
15338 "%s: IE length is wrong %d", __func__, eLen);
15339 return FALSE;
15340 }
15341 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
15342 {
15343 /* OUI - 0x00 0X50 0XF2
15344 WPA Information Element - 0x01
15345 WPA version - 0x01*/
15346 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
15347 return TRUE;
15348 }
15349 ie += eLen;
15350 remLen -= eLen;
15351 }
15352 return FALSE;
15353}
15354
15355/*
Jeff Johnson295189b2012-06-20 16:38:30 -070015356 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015357 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015358 * parameters during connect operation.
15359 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015360int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015361 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015362 )
Jeff Johnson295189b2012-06-20 16:38:30 -070015363{
15364 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015365 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015366 ENTER();
15367
15368 /*set wpa version*/
15369 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
15370
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015371 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015372 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053015373 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015374 {
15375 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15376 }
15377 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
15378 {
15379 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15380 }
15381 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015382
15383 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015384 pWextState->wpaVersion);
15385
15386 /*set authentication type*/
15387 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
15388
15389 if (0 > status)
15390 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015391 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015392 "%s: failed to set authentication type ", __func__);
15393 return status;
15394 }
15395
15396 /*set key mgmt type*/
15397 if (req->crypto.n_akm_suites)
15398 {
15399 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
15400 if (0 > status)
15401 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015402 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070015403 __func__);
15404 return status;
15405 }
15406 }
15407
15408 /*set pairwise cipher type*/
15409 if (req->crypto.n_ciphers_pairwise)
15410 {
15411 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
15412 req->crypto.ciphers_pairwise[0], true);
15413 if (0 > status)
15414 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015415 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015416 "%s: failed to set unicast cipher type", __func__);
15417 return status;
15418 }
15419 }
15420 else
15421 {
15422 /*Reset previous cipher suite to none*/
15423 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
15424 if (0 > status)
15425 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015426 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015427 "%s: failed to set unicast cipher type", __func__);
15428 return status;
15429 }
15430 }
15431
15432 /*set group cipher type*/
15433 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
15434 false);
15435
15436 if (0 > status)
15437 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015438 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070015439 __func__);
15440 return status;
15441 }
15442
Chet Lanctot186b5732013-03-18 10:26:30 -070015443#ifdef WLAN_FEATURE_11W
15444 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
15445#endif
15446
Jeff Johnson295189b2012-06-20 16:38:30 -070015447 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
15448 if (req->ie_len)
15449 {
15450 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
15451 if ( 0 > status)
15452 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015453 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015454 __func__);
15455 return status;
15456 }
15457 }
15458
15459 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015460 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015461 {
15462 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
15463 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
15464 )
15465 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015466 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070015467 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
15468 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015469 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015470 __func__);
15471 return -EOPNOTSUPP;
15472 }
15473 else
15474 {
15475 u8 key_len = req->key_len;
15476 u8 key_idx = req->key_idx;
15477
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015478 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015479 && (CSR_MAX_NUM_KEY > key_idx)
15480 )
15481 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015482 hddLog(VOS_TRACE_LEVEL_INFO,
15483 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015484 __func__, key_idx, key_len);
15485 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015486 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070015487 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015488 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015489 (u8)key_len;
15490 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
15491 }
15492 }
15493 }
15494 }
15495
15496 return status;
15497}
15498
15499/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015500 * FUNCTION: wlan_hdd_try_disconnect
15501 * This function is used to disconnect from previous
15502 * connection
15503 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053015504int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015505{
15506 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015507 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015508 hdd_station_ctx_t *pHddStaCtx;
15509 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015510 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015511
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015512 ret = wlan_hdd_validate_context(pHddCtx);
15513 if (0 != ret)
15514 {
15515 return ret;
15516 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015517 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15518
15519 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
15520
15521 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
15522 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053015523 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015524 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
15525 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053015526 /* Indicate disconnect to SME so that in-progress connection or preauth
15527 * can be aborted
15528 */
15529 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
15530 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015531 spin_lock_bh(&pAdapter->lock_for_active_session);
15532 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15533 {
15534 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15535 }
15536 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053015537 hdd_connSetConnectionState(pHddStaCtx,
15538 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015539 /* Issue disconnect to CSR */
15540 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015541 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015542 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015543 eCSR_DISCONNECT_REASON_UNSPECIFIED);
15544 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
15545 hddLog(LOG1,
15546 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
15547 } else if ( 0 != status ) {
15548 hddLog(LOGE,
15549 FL("csrRoamDisconnect failure, returned %d"),
15550 (int)status );
15551 result = -EINVAL;
15552 goto disconnected;
15553 }
15554 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015555 &pAdapter->disconnect_comp_var,
15556 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015557 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
15558 hddLog(LOGE,
15559 "%s: Failed to disconnect, timed out", __func__);
15560 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015561 }
15562 }
15563 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
15564 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015565 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015566 &pAdapter->disconnect_comp_var,
15567 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015568 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015569 {
15570 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015571 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015572 }
15573 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015574disconnected:
15575 hddLog(LOG1,
15576 FL("Set HDD connState to eConnectionState_NotConnected"));
15577 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
15578 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015579}
15580
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015581/**
15582 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
15583 * @adapter: Pointer to the HDD adapter
15584 * @req: Pointer to the structure cfg_connect_params receieved from user space
15585 *
15586 * This function will start reassociation if bssid hint, channel hint and
15587 * previous bssid parameters are present in the connect request
15588 *
15589 * Return: success if reassociation is happening
15590 * Error code if reassociation is not permitted or not happening
15591 */
15592#ifdef CFG80211_CONNECT_PREV_BSSID
15593static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15594 struct cfg80211_connect_params *req)
15595{
15596 int status = -EPERM;
15597 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
15598 hddLog(VOS_TRACE_LEVEL_INFO,
15599 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
15600 req->channel_hint->hw_value,
15601 MAC_ADDR_ARRAY(req->bssid_hint));
15602 status = hdd_reassoc(adapter, req->bssid_hint,
15603 req->channel_hint->hw_value,
15604 CONNECT_CMD_USERSPACE);
15605 }
15606 return status;
15607}
15608#else
15609static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15610 struct cfg80211_connect_params *req)
15611{
15612 return -EPERM;
15613}
15614#endif
15615
Abhishek Singhe3beee22017-07-31 15:35:40 +053015616/**
15617 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
15618 * connect in HT20 mode
15619 * @hdd_ctx: hdd context
15620 * @adapter: Pointer to the HDD adapter
15621 * @req: Pointer to the structure cfg_connect_params receieved from user space
15622 *
15623 * This function will check if supplicant has indicated to to connect in HT20
15624 * mode. this is currently applicable only for 2.4Ghz mode only.
15625 * if feature is enabled and supplicant indicate HT20 set
15626 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
15627 *
15628 * Return: void
15629 */
15630#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
15631static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
15632 hdd_adapter_t *adapter,
15633 struct cfg80211_connect_params *req)
15634{
15635 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
15636 tCsrRoamProfile *roam_profile;
15637
15638 roam_profile = &wext_state->roamProfile;
15639 roam_profile->force_24ghz_in_ht20 = false;
15640 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
15641 !(req->ht_capa.cap_info &
15642 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
15643 roam_profile->force_24ghz_in_ht20 = true;
15644
15645 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
15646 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
15647}
15648#else
15649static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
15650 hdd_adapter_t *adapter,
15651 struct cfg80211_connect_params *req)
15652{
15653 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
15654 tCsrRoamProfile *roam_profile;
15655
15656 roam_profile = &wext_state->roamProfile;
15657 roam_profile->force_24ghz_in_ht20 = false;
15658}
15659#endif
15660
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015661/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053015662 * FUNCTION: __wlan_hdd_cfg80211_connect
15663 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015664 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015665static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015666 struct net_device *ndev,
15667 struct cfg80211_connect_params *req
15668 )
15669{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015670 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015671 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053015672#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
15673 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015674 const u8 *bssid_hint = req->bssid_hint;
15675#else
15676 const u8 *bssid_hint = NULL;
15677#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015678 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015679 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053015680 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015681
15682 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015683
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015684 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15685 TRACE_CODE_HDD_CFG80211_CONNECT,
15686 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015687 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015688 "%s: device_mode = %s (%d)", __func__,
15689 hdd_device_modetoString(pAdapter->device_mode),
15690 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015691
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015692 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015693 if (!pHddCtx)
15694 {
15695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15696 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015697 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015698 }
15699
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015700 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015701 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015702 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015703 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015704 }
15705
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015706 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
15707 if (0 == status)
15708 return status;
15709
Agarwal Ashish51325b52014-06-16 16:50:49 +053015710
Jeff Johnson295189b2012-06-20 16:38:30 -070015711#ifdef WLAN_BTAMP_FEATURE
15712 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015713 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070015714 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015715 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015716 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080015717 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070015718 }
15719#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015720
15721 //If Device Mode is Station Concurrent Sessions Exit BMps
15722 //P2P Mode will be taken care in Open/close adapter
15723 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053015724 (vos_concurrent_open_sessions_running())) {
15725 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
15726 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015727 }
15728
15729 /*Try disconnecting if already in connected state*/
15730 status = wlan_hdd_try_disconnect(pAdapter);
15731 if ( 0 > status)
15732 {
15733 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15734 " connection"));
15735 return -EALREADY;
15736 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053015737 /* Check for max concurrent connections after doing disconnect if any*/
15738 if (vos_max_concurrent_connections_reached()) {
15739 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15740 return -ECONNREFUSED;
15741 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015742
Jeff Johnson295189b2012-06-20 16:38:30 -070015743 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015744 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070015745
15746 if ( 0 > status)
15747 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015748 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070015749 __func__);
15750 return status;
15751 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053015752
15753 if (pHddCtx->spoofMacAddr.isEnabled)
15754 {
15755 hddLog(VOS_TRACE_LEVEL_INFO,
15756 "%s: MAC Spoofing enabled ", __func__);
15757 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15758 * to fill TxBds for probe request during SSID scan which may happen
15759 * as part of connect command
15760 */
15761 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
15762 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
15763 if (status != VOS_STATUS_SUCCESS)
15764 return -ECONNREFUSED;
15765 }
15766
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015767 if (req->channel)
15768 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070015769 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015770 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053015771
15772 /* Abort if any scan is going on */
15773 status = wlan_hdd_scan_abort(pAdapter);
15774 if (0 != status)
15775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
15776
Abhishek Singhe3beee22017-07-31 15:35:40 +053015777 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
15778
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015779 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
15780 req->ssid_len, req->bssid,
15781 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015782
Sushant Kaushikd7083982015-03-18 14:33:24 +053015783 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015784 {
15785 //ReEnable BMPS if disabled
15786 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
15787 (NULL != pHddCtx))
15788 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053015789 if (pHddCtx->hdd_wlan_suspended)
15790 {
15791 hdd_set_pwrparams(pHddCtx);
15792 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015793 //ReEnable Bmps and Imps back
15794 hdd_enable_bmps_imps(pHddCtx);
15795 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015796 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070015797 return status;
15798 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015799 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015800 EXIT();
15801 return status;
15802}
15803
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015804static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
15805 struct net_device *ndev,
15806 struct cfg80211_connect_params *req)
15807{
15808 int ret;
15809 vos_ssr_protect(__func__);
15810 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
15811 vos_ssr_unprotect(__func__);
15812
15813 return ret;
15814}
Jeff Johnson295189b2012-06-20 16:38:30 -070015815
15816/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015817 * FUNCTION: wlan_hdd_disconnect
15818 * This function is used to issue a disconnect request to SME
15819 */
15820int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
15821{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015822 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015823 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015824 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015825 long ret;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015826 eConnectionState prev_conn_state;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015827
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015828 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015829
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015830 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015831 if (0 != status)
15832 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015833 return status;
15834 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053015835 /* Indicate sme of disconnect so that in progress connection or preauth
15836 * can be aborted
15837 */
15838 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053015839 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015840 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015841
Agarwal Ashish47d18112014-08-04 19:55:07 +053015842 /* Need to apply spin lock before decreasing active sessions
15843 * as there can be chance for double decrement if context switch
15844 * Calls hdd_DisConnectHandler.
15845 */
15846
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015847 prev_conn_state = pHddStaCtx->conn_info.connState;
15848
Agarwal Ashish47d18112014-08-04 19:55:07 +053015849 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015850 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15851 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015852 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15853 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053015854 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
15855 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singh78c691f2017-11-30 13:48:44 +053015856 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015857
Abhishek Singhf4669da2014-05-26 15:07:49 +053015858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053015859 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
15860
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015861 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015862
Mihir Shete182a0b22014-08-18 16:08:48 +053015863 /*
15864 * stop tx queues before deleting STA/BSS context from the firmware.
15865 * tx has to be disabled because the firmware can get busy dropping
15866 * the tx frames after BSS/STA has been deleted and will not send
15867 * back a response resulting in WDI timeout
15868 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053015869 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053015870 netif_tx_disable(pAdapter->dev);
15871 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015872
Mihir Shete182a0b22014-08-18 16:08:48 +053015873 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015874 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
15875 pAdapter->sessionId, reason);
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015876 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
15877 prev_conn_state != eConnectionState_Connecting)
15878 {
15879 hddLog(LOG1,
15880 FL("status = %d, already disconnected"), status);
15881 result = 0;
15882 goto disconnected;
15883 }
15884 /*
15885 * Wait here instead of returning directly, this will block the next
15886 * connect command and allow processing of the scan for ssid and
15887 * the previous connect command in CSR. Else we might hit some
15888 * race conditions leading to SME and HDD out of sync.
15889 */
15890 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015891 {
15892 hddLog(LOG1,
15893 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015894 }
15895 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015896 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015897 hddLog(LOGE,
15898 FL("csrRoamDisconnect failure, returned %d"),
15899 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015900 result = -EINVAL;
15901 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015902 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015903 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015904 &pAdapter->disconnect_comp_var,
15905 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015906 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015907 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015908 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015909 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015910 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015911 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015912disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015913 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015914 FL("Set HDD connState to eConnectionState_NotConnected"));
15915 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015916#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
15917 /* Sending disconnect event to userspace for kernel version < 3.11
15918 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
15919 */
15920 hddLog(LOG1, FL("Send disconnected event to userspace"));
15921
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053015922 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015923 WLAN_REASON_UNSPECIFIED);
15924#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015925
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015926 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015927 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015928}
15929
15930
15931/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015932 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070015933 * This function is used to issue a disconnect request to SME
15934 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015935static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015936 struct net_device *dev,
15937 u16 reason
15938 )
15939{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015940 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015941 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015942 tCsrRoamProfile *pRoamProfile;
15943 hdd_station_ctx_t *pHddStaCtx;
15944 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015945#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015946 tANI_U8 staIdx;
15947#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015948
Jeff Johnson295189b2012-06-20 16:38:30 -070015949 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015950
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015951 if (!pAdapter) {
15952 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15953 return -EINVAL;
15954 }
15955
15956 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15957 if (!pHddStaCtx) {
15958 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
15959 return -EINVAL;
15960 }
15961
15962 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15963 status = wlan_hdd_validate_context(pHddCtx);
15964 if (0 != status)
15965 {
15966 return status;
15967 }
15968
15969 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
15970
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015971 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15972 TRACE_CODE_HDD_CFG80211_DISCONNECT,
15973 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015974 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
15975 __func__, hdd_device_modetoString(pAdapter->device_mode),
15976 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015977
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015978 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
15979 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070015980
Jeff Johnson295189b2012-06-20 16:38:30 -070015981 if (NULL != pRoamProfile)
15982 {
15983 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015984 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
15985 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070015986 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015987 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070015988 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015989 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070015990 switch(reason)
15991 {
15992 case WLAN_REASON_MIC_FAILURE:
15993 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
15994 break;
15995
15996 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
15997 case WLAN_REASON_DISASSOC_AP_BUSY:
15998 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
15999 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
16000 break;
16001
16002 case WLAN_REASON_PREV_AUTH_NOT_VALID:
16003 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053016004 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070016005 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
16006 break;
16007
Jeff Johnson295189b2012-06-20 16:38:30 -070016008 default:
16009 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
16010 break;
16011 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016012 pScanInfo = &pHddCtx->scan_info;
16013 if (pScanInfo->mScanPending)
16014 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016015 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016016 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053016017 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016018 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016019 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053016020 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016021#ifdef FEATURE_WLAN_TDLS
16022 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016023 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016024 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016025 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
16026 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016027 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016028 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016029 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016031 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016032 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016033 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016034 status = sme_DeleteTdlsPeerSta(
16035 WLAN_HDD_GET_HAL_CTX(pAdapter),
16036 pAdapter->sessionId,
16037 mac);
16038 if (status != eHAL_STATUS_SUCCESS) {
16039 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16040 return -EPERM;
16041 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016042 }
16043 }
16044#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016045
16046 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
16047 reasonCode,
16048 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016049 status = wlan_hdd_disconnect(pAdapter, reasonCode);
16050 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070016051 {
16052 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016053 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016054 __func__, (int)status );
16055 return -EINVAL;
16056 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016057 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016058 else
16059 {
16060 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
16061 "called while in %d state", __func__,
16062 pHddStaCtx->conn_info.connState);
16063 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016064 }
16065 else
16066 {
16067 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
16068 }
16069
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016070 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016071 return status;
16072}
16073
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016074static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
16075 struct net_device *dev,
16076 u16 reason
16077 )
16078{
16079 int ret;
16080 vos_ssr_protect(__func__);
16081 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
16082 vos_ssr_unprotect(__func__);
16083
16084 return ret;
16085}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016086
Jeff Johnson295189b2012-06-20 16:38:30 -070016087/*
16088 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016089 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016090 * settings in IBSS mode.
16091 */
16092static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016093 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016094 struct cfg80211_ibss_params *params
16095 )
16096{
16097 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016098 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016099 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16100 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016101
Jeff Johnson295189b2012-06-20 16:38:30 -070016102 ENTER();
16103
16104 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070016105 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070016106
16107 if (params->ie_len && ( NULL != params->ie) )
16108 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016109 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16110 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016111 {
16112 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16113 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16114 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016115 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016116 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016117 tDot11fIEWPA dot11WPAIE;
16118 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016119 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016120
Wilson Yang00256342013-10-10 23:13:38 -070016121 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016122 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16123 params->ie_len, DOT11F_EID_WPA);
16124 if ( NULL != ie )
16125 {
16126 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16127 // Unpack the WPA IE
16128 //Skip past the EID byte and length byte - and four byte WiFi OUI
16129 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
16130 &ie[2+4],
16131 ie[1] - 4,
16132 &dot11WPAIE);
16133 /*Extract the multicast cipher, the encType for unicast
16134 cipher for wpa-none is none*/
16135 encryptionType =
16136 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
16137 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016138 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016139
Jeff Johnson295189b2012-06-20 16:38:30 -070016140 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
16141
16142 if (0 > status)
16143 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016144 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016145 __func__);
16146 return status;
16147 }
16148 }
16149
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016150 pWextState->roamProfile.AuthType.authType[0] =
16151 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070016152 eCSR_AUTH_TYPE_OPEN_SYSTEM;
16153
16154 if (params->privacy)
16155 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016156 /* Security enabled IBSS, At this time there is no information available
16157 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070016158 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016159 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070016160 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016161 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070016162 *enable privacy bit in beacons */
16163
16164 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
16165 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016166 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
16167 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070016168 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16169 pWextState->roamProfile.EncryptionType.numEntries = 1;
16170 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070016171 return status;
16172}
16173
16174/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016175 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016176 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016177 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016178static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016179 struct net_device *dev,
16180 struct cfg80211_ibss_params *params
16181 )
16182{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016183 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016184 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16185 tCsrRoamProfile *pRoamProfile;
16186 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016187 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16188 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016189 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070016190
16191 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016192
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016193 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16194 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
16195 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016196 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016197 "%s: device_mode = %s (%d)", __func__,
16198 hdd_device_modetoString(pAdapter->device_mode),
16199 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016200
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016201 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016202 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016203 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016204 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016205 }
16206
16207 if (NULL == pWextState)
16208 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016209 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016210 __func__);
16211 return -EIO;
16212 }
16213
Agarwal Ashish51325b52014-06-16 16:50:49 +053016214 if (vos_max_concurrent_connections_reached()) {
16215 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16216 return -ECONNREFUSED;
16217 }
16218
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016219 /*Try disconnecting if already in connected state*/
16220 status = wlan_hdd_try_disconnect(pAdapter);
16221 if ( 0 > status)
16222 {
16223 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16224 " IBSS connection"));
16225 return -EALREADY;
16226 }
16227
Jeff Johnson295189b2012-06-20 16:38:30 -070016228 pRoamProfile = &pWextState->roamProfile;
16229
16230 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
16231 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016232 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016233 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016234 return -EINVAL;
16235 }
16236
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016237 /* BSSID is provided by upper layers hence no need to AUTO generate */
16238 if (NULL != params->bssid) {
16239 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16240 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
16241 hddLog (VOS_TRACE_LEVEL_ERROR,
16242 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16243 return -EIO;
16244 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016245 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016246 }
krunal sonie9002db2013-11-25 14:24:17 -080016247 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
16248 {
16249 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16250 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
16251 {
16252 hddLog (VOS_TRACE_LEVEL_ERROR,
16253 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16254 return -EIO;
16255 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016256
16257 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080016258 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016259 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080016260 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016261
Jeff Johnson295189b2012-06-20 16:38:30 -070016262 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070016263 if (NULL !=
16264#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16265 params->chandef.chan)
16266#else
16267 params->channel)
16268#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016269 {
16270 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016271 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16272 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
16273 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16274 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016275
16276 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016277 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070016278 ieee80211_frequency_to_channel(
16279#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16280 params->chandef.chan->center_freq);
16281#else
16282 params->channel->center_freq);
16283#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016284
16285 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16286 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070016287 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016288 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
16289 __func__);
16290 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070016291 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016292
16293 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016294 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016295 if (channelNum == validChan[indx])
16296 {
16297 break;
16298 }
16299 }
16300 if (indx >= numChans)
16301 {
16302 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016303 __func__, channelNum);
16304 return -EINVAL;
16305 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016306 /* Set the Operational Channel */
16307 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
16308 channelNum);
16309 pRoamProfile->ChannelInfo.numOfChannels = 1;
16310 pHddStaCtx->conn_info.operationChannel = channelNum;
16311 pRoamProfile->ChannelInfo.ChannelList =
16312 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070016313 }
16314
16315 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016316 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070016317 if (status < 0)
16318 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016319 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070016320 __func__);
16321 return status;
16322 }
16323
16324 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016325 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053016326 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016327 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016328
16329 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016330 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016331
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016332 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016333 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016334}
16335
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016336static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
16337 struct net_device *dev,
16338 struct cfg80211_ibss_params *params
16339 )
16340{
16341 int ret = 0;
16342
16343 vos_ssr_protect(__func__);
16344 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
16345 vos_ssr_unprotect(__func__);
16346
16347 return ret;
16348}
16349
Jeff Johnson295189b2012-06-20 16:38:30 -070016350/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016351 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016352 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016353 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016354static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016355 struct net_device *dev
16356 )
16357{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016358 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016359 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16360 tCsrRoamProfile *pRoamProfile;
16361 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016362 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053016363 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016364#ifdef WLAN_FEATURE_RMC
16365 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
16366#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016367
16368 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016369
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016370 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16371 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
16372 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016373 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016374 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016375 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016376 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016377 }
16378
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016379 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
16380 hdd_device_modetoString(pAdapter->device_mode),
16381 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016382 if (NULL == pWextState)
16383 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016384 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016385 __func__);
16386 return -EIO;
16387 }
16388
16389 pRoamProfile = &pWextState->roamProfile;
16390
16391 /* Issue disconnect only if interface type is set to IBSS */
16392 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
16393 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016394 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070016395 __func__);
16396 return -EINVAL;
16397 }
16398
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016399#ifdef WLAN_FEATURE_RMC
16400 /* Clearing add IE of beacon */
16401 if (ccmCfgSetStr(pHddCtx->hHal,
16402 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
16403 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
16404 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16405 {
16406 hddLog (VOS_TRACE_LEVEL_ERROR,
16407 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
16408 return -EINVAL;
16409 }
16410 if (ccmCfgSetInt(pHddCtx->hHal,
16411 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
16412 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16413 {
16414 hddLog (VOS_TRACE_LEVEL_ERROR,
16415 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
16416 __func__);
16417 return -EINVAL;
16418 }
16419
16420 // Reset WNI_CFG_PROBE_RSP Flags
16421 wlan_hdd_reset_prob_rspies(pAdapter);
16422
16423 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16424 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
16425 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16426 {
16427 hddLog (VOS_TRACE_LEVEL_ERROR,
16428 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
16429 __func__);
16430 return -EINVAL;
16431 }
16432#endif
16433
Jeff Johnson295189b2012-06-20 16:38:30 -070016434 /* Issue Disconnect request */
16435 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053016436 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
16437 pAdapter->sessionId,
16438 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
16439 if (!HAL_STATUS_SUCCESS(hal_status)) {
16440 hddLog(LOGE,
16441 FL("sme_RoamDisconnect failed hal_status(%d)"),
16442 hal_status);
16443 return -EAGAIN;
16444 }
16445 status = wait_for_completion_timeout(
16446 &pAdapter->disconnect_comp_var,
16447 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
16448 if (!status) {
16449 hddLog(LOGE,
16450 FL("wait on disconnect_comp_var failed"));
16451 return -ETIMEDOUT;
16452 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016453
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016454 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016455 return 0;
16456}
16457
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016458static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
16459 struct net_device *dev
16460 )
16461{
16462 int ret = 0;
16463
16464 vos_ssr_protect(__func__);
16465 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
16466 vos_ssr_unprotect(__func__);
16467
16468 return ret;
16469}
16470
Jeff Johnson295189b2012-06-20 16:38:30 -070016471/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016472 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070016473 * This function is used to set the phy parameters
16474 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
16475 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016476static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016477 u32 changed)
16478{
16479 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16480 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016481 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016482
16483 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016484
16485 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016486 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
16487 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016488
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016489 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016490 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016491 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016492 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016493 }
16494
Jeff Johnson295189b2012-06-20 16:38:30 -070016495 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
16496 {
16497 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
16498 WNI_CFG_RTS_THRESHOLD_STAMAX :
16499 wiphy->rts_threshold;
16500
16501 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016502 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070016503 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016504 hddLog(VOS_TRACE_LEVEL_ERROR,
16505 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016506 __func__, rts_threshold);
16507 return -EINVAL;
16508 }
16509
16510 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
16511 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016512 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016513 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016514 hddLog(VOS_TRACE_LEVEL_ERROR,
16515 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016516 __func__, rts_threshold);
16517 return -EIO;
16518 }
16519
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016520 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016521 rts_threshold);
16522 }
16523
16524 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
16525 {
16526 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
16527 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
16528 wiphy->frag_threshold;
16529
16530 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016531 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016532 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016533 hddLog(VOS_TRACE_LEVEL_ERROR,
16534 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016535 frag_threshold);
16536 return -EINVAL;
16537 }
16538
16539 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
16540 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016541 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016542 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016543 hddLog(VOS_TRACE_LEVEL_ERROR,
16544 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016545 __func__, frag_threshold);
16546 return -EIO;
16547 }
16548
16549 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
16550 frag_threshold);
16551 }
16552
16553 if ((changed & WIPHY_PARAM_RETRY_SHORT)
16554 || (changed & WIPHY_PARAM_RETRY_LONG))
16555 {
16556 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
16557 wiphy->retry_short :
16558 wiphy->retry_long;
16559
16560 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
16561 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
16562 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016563 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016564 __func__, retry_value);
16565 return -EINVAL;
16566 }
16567
16568 if (changed & WIPHY_PARAM_RETRY_SHORT)
16569 {
16570 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
16571 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016572 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016573 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016574 hddLog(VOS_TRACE_LEVEL_ERROR,
16575 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016576 __func__, retry_value);
16577 return -EIO;
16578 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016579 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016580 __func__, retry_value);
16581 }
16582 else if (changed & WIPHY_PARAM_RETRY_SHORT)
16583 {
16584 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
16585 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016586 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016587 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016588 hddLog(VOS_TRACE_LEVEL_ERROR,
16589 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016590 __func__, retry_value);
16591 return -EIO;
16592 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016593 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016594 __func__, retry_value);
16595 }
16596 }
16597
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016598 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016599 return 0;
16600}
16601
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016602static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
16603 u32 changed)
16604{
16605 int ret;
16606
16607 vos_ssr_protect(__func__);
16608 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
16609 vos_ssr_unprotect(__func__);
16610
16611 return ret;
16612}
16613
Jeff Johnson295189b2012-06-20 16:38:30 -070016614/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016615 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070016616 * This function is used to set the txpower
16617 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016618static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070016619#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16620 struct wireless_dev *wdev,
16621#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016622#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016623 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070016624#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016625 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070016626#endif
16627 int dbm)
16628{
16629 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016630 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016631 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
16632 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016633 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016634
16635 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016636
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016637 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16638 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
16639 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016640 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016641 if (0 != status)
16642 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016643 return status;
16644 }
16645
16646 hHal = pHddCtx->hHal;
16647
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016648 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
16649 dbm, ccmCfgSetCallback,
16650 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016651 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016652 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016653 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
16654 return -EIO;
16655 }
16656
16657 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
16658 dbm);
16659
16660 switch(type)
16661 {
16662 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
16663 /* Fall through */
16664 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
16665 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
16666 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016667 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
16668 __func__);
16669 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070016670 }
16671 break;
16672 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016673 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016674 __func__);
16675 return -EOPNOTSUPP;
16676 break;
16677 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016678 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
16679 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070016680 return -EIO;
16681 }
16682
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016683 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016684 return 0;
16685}
16686
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016687static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
16688#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16689 struct wireless_dev *wdev,
16690#endif
16691#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16692 enum tx_power_setting type,
16693#else
16694 enum nl80211_tx_power_setting type,
16695#endif
16696 int dbm)
16697{
16698 int ret;
16699 vos_ssr_protect(__func__);
16700 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
16701#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16702 wdev,
16703#endif
16704#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16705 type,
16706#else
16707 type,
16708#endif
16709 dbm);
16710 vos_ssr_unprotect(__func__);
16711
16712 return ret;
16713}
16714
Jeff Johnson295189b2012-06-20 16:38:30 -070016715/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016716 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070016717 * This function is used to read the txpower
16718 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016719static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070016720#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16721 struct wireless_dev *wdev,
16722#endif
16723 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070016724{
16725
16726 hdd_adapter_t *pAdapter;
16727 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016728 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016729
Jeff Johnsone7245742012-09-05 17:12:55 -070016730 ENTER();
16731
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016732 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016733 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016734 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016735 *dbm = 0;
16736 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016737 }
16738
Jeff Johnson295189b2012-06-20 16:38:30 -070016739 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
16740 if (NULL == pAdapter)
16741 {
16742 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
16743 return -ENOENT;
16744 }
16745
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016746 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16747 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
16748 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070016749 wlan_hdd_get_classAstats(pAdapter);
16750 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
16751
Jeff Johnsone7245742012-09-05 17:12:55 -070016752 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016753 return 0;
16754}
16755
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016756static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
16757#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16758 struct wireless_dev *wdev,
16759#endif
16760 int *dbm)
16761{
16762 int ret;
16763
16764 vos_ssr_protect(__func__);
16765 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
16766#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16767 wdev,
16768#endif
16769 dbm);
16770 vos_ssr_unprotect(__func__);
16771
16772 return ret;
16773}
16774
Dustin Brown8c1d4092017-07-28 18:08:01 +053016775/*
16776 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
16777 * @stats: summary stats to use as a source
16778 * @info: kernel station_info struct to use as a destination
16779 *
16780 * Return: None
16781 */
16782static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
16783 struct station_info *info)
16784{
16785 int i;
16786
16787 info->rx_packets = stats->rx_frm_cnt;
16788 info->tx_packets = 0;
16789 info->tx_retries = 0;
16790 info->tx_failed = 0;
16791
16792 for (i = 0; i < 4; ++i) {
16793 info->tx_packets += stats->tx_frm_cnt[i];
16794 info->tx_retries += stats->multiple_retry_cnt[i];
16795 info->tx_failed += stats->fail_cnt[i];
16796 }
16797
16798 info->filled |= STATION_INFO_TX_PACKETS |
16799 STATION_INFO_TX_RETRIES |
16800 STATION_INFO_TX_FAILED |
16801 STATION_INFO_RX_PACKETS;
16802}
16803
16804/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053016805 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
16806 * @adapter: sap adapter pointer
16807 * @staid: station id of the client
16808 * @rssi: rssi value to fill
16809 *
16810 * Return: None
16811 */
16812static void
16813wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
16814{
16815 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
16816
16817 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
16818}
16819
16820/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053016821 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
16822 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053016823 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053016824 * @info: kernel station_info struct to populate
16825 *
16826 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
16827 * support "station dump" and "station get" for SAP vdevs, even though they
16828 * aren't technically stations.
16829 *
16830 * Return: errno
16831 */
16832static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053016833wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
16834#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16835 const u8* mac,
16836#else
16837 u8* mac,
16838#endif
16839 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053016840{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053016841 v_MACADDR_t *peerMacAddr;
16842 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053016843 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053016844 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053016845
16846 status = wlan_hdd_get_station_stats(adapter);
16847 if (!VOS_IS_STATUS_SUCCESS(status)) {
16848 hddLog(VOS_TRACE_LEVEL_ERROR,
16849 "Failed to get SAP stats; status:%d", status);
16850 return 0;
16851 }
16852
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053016853 peerMacAddr = (v_MACADDR_t *)mac;
16854 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
16855 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
16856 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
16857
16858 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
16859 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
16860 info->filled |= STATION_INFO_SIGNAL;
16861 }
16862
Dustin Brown8c1d4092017-07-28 18:08:01 +053016863 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
16864
16865 return 0;
16866}
16867
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016868static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016869#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16870 const u8* mac,
16871#else
16872 u8* mac,
16873#endif
16874 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070016875{
16876 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
16877 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16878 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053016879 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016880
16881 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
16882 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070016883
16884 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
16885 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
16886 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
16887 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
16888 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
16889 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
16890 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053016891 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070016892 tANI_U16 myRate;
16893 tANI_U16 currentRate = 0;
16894 tANI_U8 maxSpeedMCS = 0;
16895 tANI_U8 maxMCSIdx = 0;
16896 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053016897 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070016898 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016899 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016900
Leo Chang6f8870f2013-03-26 18:11:36 -070016901#ifdef WLAN_FEATURE_11AC
16902 tANI_U32 vht_mcs_map;
16903 eDataRate11ACMaxMcs vhtMaxMcs;
16904#endif /* WLAN_FEATURE_11AC */
16905
Jeff Johnsone7245742012-09-05 17:12:55 -070016906 ENTER();
16907
Dustin Brown8c1d4092017-07-28 18:08:01 +053016908 status = wlan_hdd_validate_context(pHddCtx);
16909 if (0 != status)
16910 {
16911 return status;
16912 }
16913
16914 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053016915 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053016916
Jeff Johnson295189b2012-06-20 16:38:30 -070016917 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
16918 (0 == ssidlen))
16919 {
16920 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
16921 " Invalid ssidlen, %d", __func__, ssidlen);
16922 /*To keep GUI happy*/
16923 return 0;
16924 }
16925
Mukul Sharma811205f2014-07-09 21:07:30 +053016926 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16927 {
16928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16929 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053016930 /* return a cached value */
16931 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053016932 return 0;
16933 }
16934
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053016935 wlan_hdd_get_station_stats(pAdapter);
16936 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016937
Kiet Lam3b17fc82013-09-27 05:24:08 +053016938 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053016939 wlan_hdd_get_snr(pAdapter, &snr);
16940 pHddStaCtx->conn_info.signal = sinfo->signal;
16941 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Kiet Lam3b17fc82013-09-27 05:24:08 +053016942 sinfo->filled |= STATION_INFO_SIGNAL;
16943
c_hpothu09f19542014-05-30 21:53:31 +053016944 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053016945 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
16946 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053016947 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053016948 {
16949 rate_flags = pAdapter->maxRateFlags;
16950 }
c_hpothu44ff4e02014-05-08 00:13:57 +053016951
Jeff Johnson295189b2012-06-20 16:38:30 -070016952 //convert to the UI units of 100kbps
16953 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
16954
16955#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070016956 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 -070016957 sinfo->signal,
16958 pCfg->reportMaxLinkSpeed,
16959 myRate,
16960 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016961 (int) pCfg->linkSpeedRssiMid,
16962 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070016963 (int) rate_flags,
16964 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070016965#endif //LINKSPEED_DEBUG_ENABLED
16966
16967 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
16968 {
16969 // we do not want to necessarily report the current speed
16970 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
16971 {
16972 // report the max possible speed
16973 rssidx = 0;
16974 }
16975 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
16976 {
16977 // report the max possible speed with RSSI scaling
16978 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
16979 {
16980 // report the max possible speed
16981 rssidx = 0;
16982 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016983 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070016984 {
16985 // report middle speed
16986 rssidx = 1;
16987 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016988 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
16989 {
16990 // report middle speed
16991 rssidx = 2;
16992 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016993 else
16994 {
16995 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016996 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070016997 }
16998 }
16999 else
17000 {
17001 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
17002 hddLog(VOS_TRACE_LEVEL_ERROR,
17003 "%s: Invalid value for reportMaxLinkSpeed: %u",
17004 __func__, pCfg->reportMaxLinkSpeed);
17005 rssidx = 0;
17006 }
17007
17008 maxRate = 0;
17009
17010 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017011 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
17012 OperationalRates, &ORLeng))
17013 {
17014 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17015 /*To keep GUI happy*/
17016 return 0;
17017 }
17018
Jeff Johnson295189b2012-06-20 16:38:30 -070017019 for (i = 0; i < ORLeng; i++)
17020 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017021 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017022 {
17023 /* Validate Rate Set */
17024 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
17025 {
17026 currentRate = supported_data_rate[j].supported_rate[rssidx];
17027 break;
17028 }
17029 }
17030 /* Update MAX rate */
17031 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17032 }
17033
17034 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017035 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
17036 ExtendedRates, &ERLeng))
17037 {
17038 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17039 /*To keep GUI happy*/
17040 return 0;
17041 }
17042
Jeff Johnson295189b2012-06-20 16:38:30 -070017043 for (i = 0; i < ERLeng; i++)
17044 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017045 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017046 {
17047 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
17048 {
17049 currentRate = supported_data_rate[j].supported_rate[rssidx];
17050 break;
17051 }
17052 }
17053 /* Update MAX rate */
17054 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17055 }
c_hpothu79aab322014-07-14 21:11:01 +053017056
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017057 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053017058 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017059 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053017060 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070017061 {
c_hpothu79aab322014-07-14 21:11:01 +053017062 if (rate_flags & eHAL_TX_RATE_VHT80)
17063 mode = 2;
17064 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
17065 mode = 1;
17066 else
17067 mode = 0;
17068
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017069 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
17070 MCSRates, &MCSLeng))
17071 {
17072 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17073 /*To keep GUI happy*/
17074 return 0;
17075 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017076 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070017077#ifdef WLAN_FEATURE_11AC
17078 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017079 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070017080 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017081 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017082 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070017083 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070017084 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017085 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017086 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017087 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070017088 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017089 maxMCSIdx = 7;
17090 }
17091 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
17092 {
17093 maxMCSIdx = 8;
17094 }
17095 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
17096 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017097 //VHT20 is supporting 0~8
17098 if (rate_flags & eHAL_TX_RATE_VHT20)
17099 maxMCSIdx = 8;
17100 else
17101 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070017102 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017103
c_hpothu79aab322014-07-14 21:11:01 +053017104 if (0 != rssidx)/*check for scaled */
17105 {
17106 //get middle rate MCS index if rssi=1/2
17107 for (i=0; i <= maxMCSIdx; i++)
17108 {
17109 if (sinfo->signal <= rssiMcsTbl[mode][i])
17110 {
17111 maxMCSIdx = i;
17112 break;
17113 }
17114 }
17115 }
17116
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017117 if (rate_flags & eHAL_TX_RATE_VHT80)
17118 {
17119 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
17120 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
17121 }
17122 else if (rate_flags & eHAL_TX_RATE_VHT40)
17123 {
17124 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
17125 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
17126 }
17127 else if (rate_flags & eHAL_TX_RATE_VHT20)
17128 {
17129 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
17130 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
17131 }
17132
Leo Chang6f8870f2013-03-26 18:11:36 -070017133 maxSpeedMCS = 1;
17134 if (currentRate > maxRate)
17135 {
17136 maxRate = currentRate;
17137 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017138
Leo Chang6f8870f2013-03-26 18:11:36 -070017139 }
17140 else
17141#endif /* WLAN_FEATURE_11AC */
17142 {
17143 if (rate_flags & eHAL_TX_RATE_HT40)
17144 {
17145 rateFlag |= 1;
17146 }
17147 if (rate_flags & eHAL_TX_RATE_SGI)
17148 {
17149 rateFlag |= 2;
17150 }
17151
Girish Gowli01abcee2014-07-31 20:18:55 +053017152 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053017153 if (rssidx == 1 || rssidx == 2)
17154 {
17155 //get middle rate MCS index if rssi=1/2
17156 for (i=0; i <= 7; i++)
17157 {
17158 if (sinfo->signal <= rssiMcsTbl[mode][i])
17159 {
17160 temp = i+1;
17161 break;
17162 }
17163 }
17164 }
c_hpothu79aab322014-07-14 21:11:01 +053017165
17166 for (i = 0; i < MCSLeng; i++)
17167 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017168 for (j = 0; j < temp; j++)
17169 {
17170 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
17171 {
17172 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017173 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017174 break;
17175 }
17176 }
17177 if ((j < temp) && (currentRate > maxRate))
17178 {
17179 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070017180 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017181 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017182 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017183 }
17184 }
17185
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017186 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
17187 {
17188 maxRate = myRate;
17189 maxSpeedMCS = 1;
17190 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17191 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017192 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053017193 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070017194 {
17195 maxRate = myRate;
17196 if (rate_flags & eHAL_TX_RATE_LEGACY)
17197 {
17198 maxSpeedMCS = 0;
17199 }
17200 else
17201 {
17202 maxSpeedMCS = 1;
17203 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17204 }
17205 }
17206
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017207 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070017208 {
17209 sinfo->txrate.legacy = maxRate;
17210#ifdef LINKSPEED_DEBUG_ENABLED
17211 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
17212#endif //LINKSPEED_DEBUG_ENABLED
17213 }
17214 else
17215 {
17216 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070017217#ifdef WLAN_FEATURE_11AC
17218 sinfo->txrate.nss = 1;
17219 if (rate_flags & eHAL_TX_RATE_VHT80)
17220 {
17221 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017222 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070017223 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017224 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070017225 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017226 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17227 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17228 }
17229 else if (rate_flags & eHAL_TX_RATE_VHT20)
17230 {
17231 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17232 }
17233#endif /* WLAN_FEATURE_11AC */
17234 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
17235 {
17236 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17237 if (rate_flags & eHAL_TX_RATE_HT40)
17238 {
17239 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17240 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017241 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017242 if (rate_flags & eHAL_TX_RATE_SGI)
17243 {
17244 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17245 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017246
Jeff Johnson295189b2012-06-20 16:38:30 -070017247#ifdef LINKSPEED_DEBUG_ENABLED
17248 pr_info("Reporting MCS rate %d flags %x\n",
17249 sinfo->txrate.mcs,
17250 sinfo->txrate.flags );
17251#endif //LINKSPEED_DEBUG_ENABLED
17252 }
17253 }
17254 else
17255 {
17256 // report current rate instead of max rate
17257
17258 if (rate_flags & eHAL_TX_RATE_LEGACY)
17259 {
17260 //provide to the UI in units of 100kbps
17261 sinfo->txrate.legacy = myRate;
17262#ifdef LINKSPEED_DEBUG_ENABLED
17263 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
17264#endif //LINKSPEED_DEBUG_ENABLED
17265 }
17266 else
17267 {
17268 //must be MCS
17269 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017270#ifdef WLAN_FEATURE_11AC
17271 sinfo->txrate.nss = 1;
17272 if (rate_flags & eHAL_TX_RATE_VHT80)
17273 {
17274 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17275 }
17276 else
17277#endif /* WLAN_FEATURE_11AC */
17278 {
17279 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17280 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017281 if (rate_flags & eHAL_TX_RATE_SGI)
17282 {
17283 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17284 }
17285 if (rate_flags & eHAL_TX_RATE_HT40)
17286 {
17287 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17288 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017289#ifdef WLAN_FEATURE_11AC
17290 else if (rate_flags & eHAL_TX_RATE_VHT80)
17291 {
17292 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
17293 }
17294#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070017295#ifdef LINKSPEED_DEBUG_ENABLED
17296 pr_info("Reporting actual MCS rate %d flags %x\n",
17297 sinfo->txrate.mcs,
17298 sinfo->txrate.flags );
17299#endif //LINKSPEED_DEBUG_ENABLED
17300 }
17301 }
17302 sinfo->filled |= STATION_INFO_TX_BITRATE;
17303
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017304 sinfo->tx_packets =
17305 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
17306 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
17307 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
17308 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
17309
17310 sinfo->tx_retries =
17311 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
17312 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
17313 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
17314 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
17315
17316 sinfo->tx_failed =
17317 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
17318 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
17319 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
17320 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
17321
17322 sinfo->filled |=
17323 STATION_INFO_TX_PACKETS |
17324 STATION_INFO_TX_RETRIES |
17325 STATION_INFO_TX_FAILED;
17326
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017327 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
17328 sinfo->filled |= STATION_INFO_RX_PACKETS;
17329
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017330 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
17331 &sinfo->txrate, sizeof(sinfo->txrate));
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017332 if (rate_flags & eHAL_TX_RATE_LEGACY)
17333 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
17334 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
17335 sinfo->rx_packets);
17336 else
17337 hddLog(LOG1,
17338 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
17339 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
17340 sinfo->tx_packets, sinfo->rx_packets);
17341
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017342 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17343 TRACE_CODE_HDD_CFG80211_GET_STA,
17344 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017345 EXIT();
17346 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017347}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017348#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17349static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17350 const u8* mac, struct station_info *sinfo)
17351#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017352static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17353 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017354#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017355{
17356 int ret;
17357
17358 vos_ssr_protect(__func__);
17359 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
17360 vos_ssr_unprotect(__func__);
17361
17362 return ret;
17363}
17364
17365static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070017366 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070017367{
17368 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017369 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017370 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017371 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017372
Jeff Johnsone7245742012-09-05 17:12:55 -070017373 ENTER();
17374
Jeff Johnson295189b2012-06-20 16:38:30 -070017375 if (NULL == pAdapter)
17376 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017377 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017378 return -ENODEV;
17379 }
17380
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017381 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17382 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
17383 pAdapter->sessionId, timeout));
17384
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017385 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017386 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017387 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017388 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017389 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017390 }
17391
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017392 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
17393 (TRUE == pHddCtx->hdd_wlan_suspended) &&
17394 (pHddCtx->cfg_ini->fhostArpOffload) &&
17395 (eConnectionState_Associated ==
17396 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
17397 {
Amar Singhald53568e2013-09-26 11:03:45 -070017398
17399 hddLog(VOS_TRACE_LEVEL_INFO,
17400 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053017401 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017402 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17403 {
17404 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017405 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017406 __func__, vos_status);
17407 }
17408 }
17409
Jeff Johnson295189b2012-06-20 16:38:30 -070017410 /**The get power cmd from the supplicant gets updated by the nl only
17411 *on successful execution of the function call
17412 *we are oppositely mapped w.r.t mode in the driver
17413 **/
17414 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
17415
17416 if (VOS_STATUS_E_FAILURE == vos_status)
17417 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17419 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017420 return -EINVAL;
17421 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017422 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017423 return 0;
17424}
17425
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017426static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
17427 struct net_device *dev, bool mode, int timeout)
17428{
17429 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017430
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017431 vos_ssr_protect(__func__);
17432 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
17433 vos_ssr_unprotect(__func__);
17434
17435 return ret;
17436}
Sushant Kaushik084f6592015-09-10 13:11:56 +053017437
Jeff Johnson295189b2012-06-20 16:38:30 -070017438#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017439static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
17440 struct net_device *netdev,
17441 u8 key_index)
17442{
17443 ENTER();
17444 return 0;
17445}
17446
Jeff Johnson295189b2012-06-20 16:38:30 -070017447static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017448 struct net_device *netdev,
17449 u8 key_index)
17450{
17451 int ret;
17452 vos_ssr_protect(__func__);
17453 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
17454 vos_ssr_unprotect(__func__);
17455 return ret;
17456}
17457#endif //LINUX_VERSION_CODE
17458
17459#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17460static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17461 struct net_device *dev,
17462 struct ieee80211_txq_params *params)
17463{
17464 ENTER();
17465 return 0;
17466}
17467#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17468static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17469 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017470{
Jeff Johnsone7245742012-09-05 17:12:55 -070017471 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070017472 return 0;
17473}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017474#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070017475
17476#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17477static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017478 struct net_device *dev,
17479 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017480{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017481 int ret;
17482
17483 vos_ssr_protect(__func__);
17484 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
17485 vos_ssr_unprotect(__func__);
17486 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017487}
17488#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17489static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
17490 struct ieee80211_txq_params *params)
17491{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017492 int ret;
17493
17494 vos_ssr_protect(__func__);
17495 ret = __wlan_hdd_set_txq_params(wiphy, params);
17496 vos_ssr_unprotect(__func__);
17497 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017498}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017499#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017500
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017501static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017502 struct net_device *dev,
17503 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070017504{
17505 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017506 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017507 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017508 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017509 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017510 v_CONTEXT_t pVosContext = NULL;
17511 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017512
Jeff Johnsone7245742012-09-05 17:12:55 -070017513 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017514
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017515 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070017516 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017517 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017518 return -EINVAL;
17519 }
17520
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017521 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17522 TRACE_CODE_HDD_CFG80211_DEL_STA,
17523 pAdapter->sessionId, pAdapter->device_mode));
17524
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017525 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17526 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017527 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017528 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017529 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017530 }
17531
Jeff Johnson295189b2012-06-20 16:38:30 -070017532 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017533 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017534 )
17535 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017536 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
17537 pSapCtx = VOS_GET_SAP_CB(pVosContext);
17538 if(pSapCtx == NULL){
17539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17540 FL("psapCtx is NULL"));
17541 return -ENOENT;
17542 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053017543 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
17544 {
17545 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
17546 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
17547 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
17548 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017549 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070017550 {
17551 v_U16_t i;
17552 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
17553 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017554 if ((pSapCtx->aStaInfo[i].isUsed) &&
17555 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070017556 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017557 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017558 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017559 ETHER_ADDR_LEN);
17560
Jeff Johnson295189b2012-06-20 16:38:30 -070017561 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017562 "%s: Delete STA with MAC::"
17563 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017564 __func__,
17565 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
17566 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070017567 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017568 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017569 }
17570 }
17571 }
17572 else
17573 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017574
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017575 vos_status = hdd_softap_GetStaId(pAdapter,
17576 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017577 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17578 {
17579 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017580 "%s: Skip this DEL STA as this is not used::"
17581 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017582 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017583 return -ENOENT;
17584 }
17585
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017586 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017587 {
17588 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017589 "%s: Skip this DEL STA as deauth is in progress::"
17590 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017591 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017592 return -ENOENT;
17593 }
17594
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017595 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017596
Jeff Johnson295189b2012-06-20 16:38:30 -070017597 hddLog(VOS_TRACE_LEVEL_INFO,
17598 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080017599 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017600 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017601 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017602
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017603 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017604 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17605 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017606 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017607 hddLog(VOS_TRACE_LEVEL_INFO,
17608 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080017609 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017610 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017611 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017612 return -ENOENT;
17613 }
17614
Jeff Johnson295189b2012-06-20 16:38:30 -070017615 }
17616 }
17617
17618 EXIT();
17619
17620 return 0;
17621}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017622
17623#ifdef CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053017624int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017625 struct net_device *dev,
17626 struct station_del_parameters *param)
17627#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017628#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053017629int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017630 struct net_device *dev, const u8 *mac)
17631#else
Kapil Gupta137ef892016-12-13 19:38:00 +053017632int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017633 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017634#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017635#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017636{
17637 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017638 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070017639
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017640 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017641
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017642#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017643 if (NULL == param) {
17644 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017645 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017646 return -EINVAL;
17647 }
17648
17649 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
17650 param->subtype, &delStaParams);
17651
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017652#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053017653 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017654 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017655#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017656 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
17657
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017658 vos_ssr_unprotect(__func__);
17659
17660 return ret;
17661}
17662
17663static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017664 struct net_device *dev,
17665#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17666 const u8 *mac,
17667#else
17668 u8 *mac,
17669#endif
17670 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017671{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017672 hdd_adapter_t *pAdapter;
17673 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017674 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017675#ifdef FEATURE_WLAN_TDLS
17676 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017677
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017678 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017679
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017680 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17681 if (NULL == pAdapter)
17682 {
17683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17684 "%s: Adapter is NULL",__func__);
17685 return -EINVAL;
17686 }
17687 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17688 status = wlan_hdd_validate_context(pHddCtx);
17689 if (0 != status)
17690 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017691 return status;
17692 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017693
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017694 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17695 TRACE_CODE_HDD_CFG80211_ADD_STA,
17696 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017697 mask = params->sta_flags_mask;
17698
17699 set = params->sta_flags_set;
17700
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017702 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
17703 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017704
17705 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
17706 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080017707 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017708 }
17709 }
17710#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017711 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017712 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017713}
17714
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017715#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17716static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
17717 struct net_device *dev, const u8 *mac,
17718 struct station_parameters *params)
17719#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017720static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
17721 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017722#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017723{
17724 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017725
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017726 vos_ssr_protect(__func__);
17727 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
17728 vos_ssr_unprotect(__func__);
17729
17730 return ret;
17731}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017732#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070017733
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017734static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070017735 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017736{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017737 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17738 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017739 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017740 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017741 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017742 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070017743
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017744 ENTER();
17745
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017746 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017747 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017748 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017749 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017750 return -EINVAL;
17751 }
17752
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017753 if (!pmksa) {
17754 hddLog(LOGE, FL("pmksa is NULL"));
17755 return -EINVAL;
17756 }
17757
17758 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070017759 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017760 pmksa->bssid, pmksa->pmkid);
17761 return -EINVAL;
17762 }
17763
17764 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
17765 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17766
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017767 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17768 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017769 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017770 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017771 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017772 }
17773
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017774 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017775 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17776
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017777 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
17778 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017779
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017780 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017781 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017782 &pmk_id, 1, FALSE);
17783
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017784 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17785 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
17786 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017787
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017788 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017789 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017790}
17791
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017792static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
17793 struct cfg80211_pmksa *pmksa)
17794{
17795 int ret;
17796
17797 vos_ssr_protect(__func__);
17798 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
17799 vos_ssr_unprotect(__func__);
17800
17801 return ret;
17802}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017803
Wilson Yang6507c4e2013-10-01 20:11:19 -070017804
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017805static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070017806 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017807{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017808 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17809 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017810 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017811 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017812
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017813 ENTER();
17814
Wilson Yang6507c4e2013-10-01 20:11:19 -070017815 /* Validate pAdapter */
17816 if (NULL == pAdapter)
17817 {
17818 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
17819 return -EINVAL;
17820 }
17821
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017822 if (!pmksa) {
17823 hddLog(LOGE, FL("pmksa is NULL"));
17824 return -EINVAL;
17825 }
17826
17827 if (!pmksa->bssid) {
17828 hddLog(LOGE, FL("pmksa->bssid is NULL"));
17829 return -EINVAL;
17830 }
17831
Kiet Lam98c46a12014-10-31 15:34:57 -070017832 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
17833 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17834
Wilson Yang6507c4e2013-10-01 20:11:19 -070017835 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17836 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017837 if (0 != status)
17838 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017839 return status;
17840 }
17841
17842 /*Retrieve halHandle*/
17843 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17844
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017845 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17846 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
17847 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017848 /* Delete the PMKID CSR cache */
17849 if (eHAL_STATUS_SUCCESS !=
17850 sme_RoamDelPMKIDfromCache(halHandle,
17851 pAdapter->sessionId, pmksa->bssid, FALSE)) {
17852 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
17853 MAC_ADDR_ARRAY(pmksa->bssid));
17854 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017855 }
17856
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017857 EXIT();
17858 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017859}
17860
Wilson Yang6507c4e2013-10-01 20:11:19 -070017861
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017862static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
17863 struct cfg80211_pmksa *pmksa)
17864{
17865 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017866
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017867 vos_ssr_protect(__func__);
17868 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
17869 vos_ssr_unprotect(__func__);
17870
17871 return ret;
17872
17873}
17874
17875static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017876{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017877 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17878 tHalHandle halHandle;
17879 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017880 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017881
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017882 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070017883
17884 /* Validate pAdapter */
17885 if (NULL == pAdapter)
17886 {
17887 hddLog(VOS_TRACE_LEVEL_ERROR,
17888 "%s: Invalid Adapter" ,__func__);
17889 return -EINVAL;
17890 }
17891
17892 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17893 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017894 if (0 != status)
17895 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017896 return status;
17897 }
17898
17899 /*Retrieve halHandle*/
17900 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17901
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017902 /* Flush the PMKID cache in CSR */
17903 if (eHAL_STATUS_SUCCESS !=
17904 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
17905 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
17906 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017907 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017908 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080017909 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017910}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017911
17912static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
17913{
17914 int ret;
17915
17916 vos_ssr_protect(__func__);
17917 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
17918 vos_ssr_unprotect(__func__);
17919
17920 return ret;
17921}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017922#endif
17923
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017924#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017925static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17926 struct net_device *dev,
17927 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017928{
17929 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17930 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017931 hdd_context_t *pHddCtx;
17932 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017933
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017934 ENTER();
17935
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017936 if (NULL == pAdapter)
17937 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017938 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017939 return -ENODEV;
17940 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017941 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17942 ret = wlan_hdd_validate_context(pHddCtx);
17943 if (0 != ret)
17944 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017945 return ret;
17946 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017947 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017948 if (NULL == pHddStaCtx)
17949 {
17950 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
17951 return -EINVAL;
17952 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017953
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017954 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17955 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
17956 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017957 // Added for debug on reception of Re-assoc Req.
17958 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
17959 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017960 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017961 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080017962 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017963 }
17964
17965#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080017966 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017967 ftie->ie_len);
17968#endif
17969
17970 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053017971 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
17972 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017973 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017974
17975 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017976 return 0;
17977}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017978
17979static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17980 struct net_device *dev,
17981 struct cfg80211_update_ft_ies_params *ftie)
17982{
17983 int ret;
17984
17985 vos_ssr_protect(__func__);
17986 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
17987 vos_ssr_unprotect(__func__);
17988
17989 return ret;
17990}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017991#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017992
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017993#ifdef FEATURE_WLAN_SCAN_PNO
17994
17995void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
17996 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
17997{
17998 int ret;
17999 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
18000 hdd_context_t *pHddCtx;
18001
Nirav Shah80830bf2013-12-31 16:35:12 +053018002 ENTER();
18003
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018004 if (NULL == pAdapter)
18005 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018007 "%s: HDD adapter is Null", __func__);
18008 return ;
18009 }
18010
18011 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18012 if (NULL == pHddCtx)
18013 {
18014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18015 "%s: HDD context is Null!!!", __func__);
18016 return ;
18017 }
18018
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018019 spin_lock(&pHddCtx->schedScan_lock);
18020 if (TRUE == pHddCtx->isWiphySuspended)
18021 {
18022 pHddCtx->isSchedScanUpdatePending = TRUE;
18023 spin_unlock(&pHddCtx->schedScan_lock);
18024 hddLog(VOS_TRACE_LEVEL_INFO,
18025 "%s: Update cfg80211 scan database after it resume", __func__);
18026 return ;
18027 }
18028 spin_unlock(&pHddCtx->schedScan_lock);
18029
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018030 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
18031
18032 if (0 > ret)
18033 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053018034 else
18035 {
18036 /* Acquire wakelock to handle the case where APP's tries to suspend
18037 * immediatly after the driver gets connect request(i.e after pno)
18038 * from supplicant, this result in app's is suspending and not able
18039 * to process the connect request to AP */
18040 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
18041 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018042 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18044 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018045}
18046
18047/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018048 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018049 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018050 */
18051static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
18052{
18053 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
18054 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018055 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018056 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18057 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053018058
18059 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
18060 {
18061 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18062 "%s: PNO is allowed only in STA interface", __func__);
18063 return eHAL_STATUS_FAILURE;
18064 }
18065
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018066 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
18067
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018068 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053018069 * active sessions. PNO is allowed only in case when sap session
18070 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018071 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018072 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
18073 {
18074 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018075 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018076
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018077 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
18078 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
18079 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
18080 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053018081 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
18082 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053018083 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018084 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018085 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018086 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018087 }
18088 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
18089 pAdapterNode = pNext;
18090 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018091 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018092}
18093
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018094void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
18095{
18096 hdd_adapter_t *pAdapter = callbackContext;
18097 hdd_context_t *pHddCtx;
18098
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018099 ENTER();
18100
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018101 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
18102 {
18103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18104 FL("Invalid adapter or adapter has invalid magic"));
18105 return;
18106 }
18107
18108 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18109 if (0 != wlan_hdd_validate_context(pHddCtx))
18110 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018111 return;
18112 }
18113
c_hpothub53c45d2014-08-18 16:53:14 +053018114 if (VOS_STATUS_SUCCESS != status)
18115 {
18116 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018117 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053018118 pHddCtx->isPnoEnable = FALSE;
18119 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018120
18121 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
18122 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018123 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018124}
18125
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018126#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
18127 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
18128/**
18129 * hdd_config_sched_scan_plan() - configures the sched scan plans
18130 * from the framework.
18131 * @pno_req: pointer to PNO scan request
18132 * @request: pointer to scan request from framework
18133 *
18134 * Return: None
18135 */
18136static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
18137 struct cfg80211_sched_scan_request *request,
18138 hdd_context_t *hdd_ctx)
18139{
18140 v_U32_t i = 0;
18141
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018142 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018143 for (i = 0; i < request->n_scan_plans; i++)
18144 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018145 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
18146 request->scan_plans[i].iterations;
18147 pno_req->scanTimers.aTimerValues[i].uTimerValue =
18148 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018149 }
18150}
18151#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018152static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018153 struct cfg80211_sched_scan_request *request,
18154 hdd_context_t *hdd_ctx)
18155{
18156 v_U32_t i, temp_int;
18157 /* Driver gets only one time interval which is hardcoded in
18158 * supplicant for 10000ms. Taking power consumption into account 6
18159 * timers will be used, Timervalue is increased exponentially
18160 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
18161 * timer is configurable through INI param gPNOScanTimerRepeatValue.
18162 * If it is set to 0 only one timer will be used and PNO scan cycle
18163 * will be repeated after each interval specified by supplicant
18164 * till PNO is disabled.
18165 */
18166 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018167 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018168 HDD_PNO_SCAN_TIMERS_SET_ONE;
18169 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018170 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018171 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
18172
18173 temp_int = (request->interval)/1000;
18174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18175 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
18176 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018177 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018178 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018179 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018180 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018181 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018182 temp_int *= 2;
18183 }
18184 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018185 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018186}
18187#endif
18188
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018189/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018190 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
18191 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018192 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018193static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018194 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18195{
18196 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018197 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018198 hdd_context_t *pHddCtx;
18199 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018200 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053018201 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
18202 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018203 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
18204 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018205 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018206 hdd_config_t *pConfig = NULL;
18207 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018208
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018209 ENTER();
18210
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018211 if (NULL == pAdapter)
18212 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018214 "%s: HDD adapter is Null", __func__);
18215 return -ENODEV;
18216 }
18217
18218 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018219 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018220
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018221 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018222 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018223 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018224 }
18225
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018226 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018227 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18228 if (NULL == hHal)
18229 {
18230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18231 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018232 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018233 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018234 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18235 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
18236 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018237 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053018238 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018239 {
18240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18241 "%s: aborting the existing scan is unsuccessfull", __func__);
18242 return -EBUSY;
18243 }
18244
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018245 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018246 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018248 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018249 return -EBUSY;
18250 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018251
c_hpothu37f21312014-04-09 21:49:54 +053018252 if (TRUE == pHddCtx->isPnoEnable)
18253 {
18254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
18255 FL("already PNO is enabled"));
18256 return -EBUSY;
18257 }
c_hpothu225aa7c2014-10-22 17:45:13 +053018258
18259 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
18260 {
18261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18262 "%s: abort ROC failed ", __func__);
18263 return -EBUSY;
18264 }
18265
c_hpothu37f21312014-04-09 21:49:54 +053018266 pHddCtx->isPnoEnable = TRUE;
18267
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018268 pnoRequest.enable = 1; /*Enable PNO */
18269 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018270
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018271 if (( !pnoRequest.ucNetworksCount ) ||
18272 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018273 {
18274 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018275 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018276 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018277 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018278 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018279 goto error;
18280 }
18281
18282 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
18283 {
18284 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018285 "%s: Incorrect number of channels %d",
18286 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018287 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018288 goto error;
18289 }
18290
18291 /* Framework provides one set of channels(all)
18292 * common for all saved profile */
18293 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
18294 channels_allowed, &num_channels_allowed))
18295 {
18296 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18297 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018298 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018299 goto error;
18300 }
18301 /* Checking each channel against allowed channel list */
18302 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053018303 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018304 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018305 char chList [(request->n_channels*5)+1];
18306 int len;
18307 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018308 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018309 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018310 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018311 if (request->channels[i]->hw_value == channels_allowed[indx])
18312 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018313 if ((!pConfig->enableDFSPnoChnlScan) &&
18314 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
18315 {
18316 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18317 "%s : Dropping DFS channel : %d",
18318 __func__,channels_allowed[indx]);
18319 num_ignore_dfs_ch++;
18320 break;
18321 }
18322
Nirav Shah80830bf2013-12-31 16:35:12 +053018323 valid_ch[num_ch++] = request->channels[i]->hw_value;
18324 len += snprintf(chList+len, 5, "%d ",
18325 request->channels[i]->hw_value);
18326 break ;
18327 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018328 }
18329 }
Nirav Shah80830bf2013-12-31 16:35:12 +053018330 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018331
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018332 /*If all channels are DFS and dropped, then ignore the PNO request*/
18333 if (num_ignore_dfs_ch == request->n_channels)
18334 {
18335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18336 "%s : All requested channels are DFS channels", __func__);
18337 ret = -EINVAL;
18338 goto error;
18339 }
18340 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018341
18342 pnoRequest.aNetworks =
18343 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18344 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018345 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018346 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18347 FL("failed to allocate memory aNetworks %u"),
18348 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18349 goto error;
18350 }
18351 vos_mem_zero(pnoRequest.aNetworks,
18352 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18353
18354 /* Filling per profile params */
18355 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
18356 {
18357 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018358 request->match_sets[i].ssid.ssid_len;
18359
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018360 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
18361 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018362 {
18363 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018364 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018365 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018366 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018367 goto error;
18368 }
18369
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018370 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018371 request->match_sets[i].ssid.ssid,
18372 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18374 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018375 i, pnoRequest.aNetworks[i].ssId.ssId);
18376 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
18377 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
18378 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018379
18380 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018381 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
18382 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018383
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018384 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018385 }
18386
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018387 for (i = 0; i < request->n_ssids; i++)
18388 {
18389 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018390 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018391 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018392 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018393 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018394 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018395 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018396 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018397 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018398 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018399 break;
18400 }
18401 j++;
18402 }
18403 }
18404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18405 "Number of hidden networks being Configured = %d",
18406 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080018408 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018409
18410 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18411 if (pnoRequest.p24GProbeTemplate == NULL)
18412 {
18413 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18414 FL("failed to allocate memory p24GProbeTemplate %u"),
18415 SIR_PNO_MAX_PB_REQ_SIZE);
18416 goto error;
18417 }
18418
18419 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18420 if (pnoRequest.p5GProbeTemplate == NULL)
18421 {
18422 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18423 FL("failed to allocate memory p5GProbeTemplate %u"),
18424 SIR_PNO_MAX_PB_REQ_SIZE);
18425 goto error;
18426 }
18427
18428 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18429 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18430
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053018431 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
18432 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018433 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018434 pnoRequest.us24GProbeTemplateLen = request->ie_len;
18435 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
18436 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018437
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018438 pnoRequest.us5GProbeTemplateLen = request->ie_len;
18439 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
18440 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018441 }
18442
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018443 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053018444
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018445 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018446
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018447 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018448 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
18449 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018450 pAdapter->pno_req_status = 0;
18451
Nirav Shah80830bf2013-12-31 16:35:12 +053018452 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18453 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018454 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
18455 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053018456
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018457 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018458 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018459 hdd_cfg80211_sched_scan_done_callback, pAdapter);
18460 if (eHAL_STATUS_SUCCESS != status)
18461 {
18462 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018463 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018464 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018465 goto error;
18466 }
18467
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018468 ret = wait_for_completion_timeout(
18469 &pAdapter->pno_comp_var,
18470 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
18471 if (0 >= ret)
18472 {
18473 // Did not receive the response for PNO enable in time.
18474 // Assuming the PNO enable was success.
18475 // Returning error from here, because we timeout, results
18476 // in side effect of Wifi (Wifi Setting) not to work.
18477 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18478 FL("Timed out waiting for PNO to be Enabled"));
18479 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018480 }
18481
18482 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053018483 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018484
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018485error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18487 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053018488 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018489 if (pnoRequest.aNetworks)
18490 vos_mem_free(pnoRequest.aNetworks);
18491 if (pnoRequest.p24GProbeTemplate)
18492 vos_mem_free(pnoRequest.p24GProbeTemplate);
18493 if (pnoRequest.p5GProbeTemplate)
18494 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018495
18496 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018497 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018498}
18499
18500/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018501 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
18502 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018503 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018504static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
18505 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18506{
18507 int ret;
18508
18509 vos_ssr_protect(__func__);
18510 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
18511 vos_ssr_unprotect(__func__);
18512
18513 return ret;
18514}
18515
18516/*
18517 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
18518 * Function to disable PNO
18519 */
18520static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018521 struct net_device *dev)
18522{
18523 eHalStatus status = eHAL_STATUS_FAILURE;
18524 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18525 hdd_context_t *pHddCtx;
18526 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018527 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018528 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018529
18530 ENTER();
18531
18532 if (NULL == pAdapter)
18533 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018534 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018535 "%s: HDD adapter is Null", __func__);
18536 return -ENODEV;
18537 }
18538
18539 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018540
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018541 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018542 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018544 "%s: HDD context is Null", __func__);
18545 return -ENODEV;
18546 }
18547
18548 /* The return 0 is intentional when isLogpInProgress and
18549 * isLoadUnloadInProgress. We did observe a crash due to a return of
18550 * failure in sched_scan_stop , especially for a case where the unload
18551 * of the happens at the same time. The function __cfg80211_stop_sched_scan
18552 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
18553 * success. If it returns a failure , then its next invocation due to the
18554 * clean up of the second interface will have the dev pointer corresponding
18555 * to the first one leading to a crash.
18556 */
18557 if (pHddCtx->isLogpInProgress)
18558 {
18559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18560 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053018561 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018562 return ret;
18563 }
18564
Mihir Shete18156292014-03-11 15:38:30 +053018565 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018566 {
18567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18568 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
18569 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018570 }
18571
18572 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18573 if (NULL == hHal)
18574 {
18575 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18576 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018577 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018578 }
18579
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018580 pnoRequest.enable = 0; /* Disable PNO */
18581 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018582
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018583 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18584 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
18585 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018586
18587 INIT_COMPLETION(pAdapter->pno_comp_var);
18588 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
18589 pnoRequest.callbackContext = pAdapter;
18590 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018591 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018592 pAdapter->sessionId,
18593 NULL, pAdapter);
18594 if (eHAL_STATUS_SUCCESS != status)
18595 {
18596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18597 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018598 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018599 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018600 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018601 ret = wait_for_completion_timeout(
18602 &pAdapter->pno_comp_var,
18603 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
18604 if (0 >= ret)
18605 {
18606 // Did not receive the response for PNO disable in time.
18607 // Assuming the PNO disable was success.
18608 // Returning error from here, because we timeout, results
18609 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053018610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018611 FL("Timed out waiting for PNO to be disabled"));
18612 ret = 0;
18613 }
18614
18615 ret = pAdapter->pno_req_status;
18616 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018617
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018618error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018620 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018621
18622 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018623 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018624}
18625
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018626/*
18627 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
18628 * NL interface to disable PNO
18629 */
18630static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
18631 struct net_device *dev)
18632{
18633 int ret;
18634
18635 vos_ssr_protect(__func__);
18636 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
18637 vos_ssr_unprotect(__func__);
18638
18639 return ret;
18640}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018641#endif /*FEATURE_WLAN_SCAN_PNO*/
18642
18643
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018644#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018645#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018646static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18647 struct net_device *dev,
18648 u8 *peer, u8 action_code,
18649 u8 dialog_token,
18650 u16 status_code, u32 peer_capability,
18651 const u8 *buf, size_t len)
18652#else /* TDLS_MGMT_VERSION2 */
18653#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
18654static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18655 struct net_device *dev,
18656 const u8 *peer, u8 action_code,
18657 u8 dialog_token, u16 status_code,
18658 u32 peer_capability, bool initiator,
18659 const u8 *buf, size_t len)
18660#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
18661static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18662 struct net_device *dev,
18663 const u8 *peer, u8 action_code,
18664 u8 dialog_token, u16 status_code,
18665 u32 peer_capability, const u8 *buf,
18666 size_t len)
18667#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
18668static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18669 struct net_device *dev,
18670 u8 *peer, u8 action_code,
18671 u8 dialog_token,
18672 u16 status_code, u32 peer_capability,
18673 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018674#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018675static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18676 struct net_device *dev,
18677 u8 *peer, u8 action_code,
18678 u8 dialog_token,
18679 u16 status_code, const u8 *buf,
18680 size_t len)
18681#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018682#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018683{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018684 hdd_adapter_t *pAdapter;
18685 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018686 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070018687 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080018688 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070018689 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018690 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053018691 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018692#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018693 u32 peer_capability = 0;
18694#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018695 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018696 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018697 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018698
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018699 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18700 if (NULL == pAdapter)
18701 {
18702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18703 "%s: Adapter is NULL",__func__);
18704 return -EINVAL;
18705 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018706 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18707 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
18708 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018709
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018710 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018711 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018712 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018714 "Invalid arguments");
18715 return -EINVAL;
18716 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018717
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018718 if (pHddCtx->isLogpInProgress)
18719 {
18720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18721 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053018722 wlan_hdd_tdls_set_link_status(pAdapter,
18723 peer,
18724 eTDLS_LINK_IDLE,
18725 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018726 return -EBUSY;
18727 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018728
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018729 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
18730 {
18731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18732 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
18733 return -EAGAIN;
18734 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018735
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018736 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
18737 if (!pHddTdlsCtx) {
18738 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18739 "%s: pHddTdlsCtx not valid.", __func__);
18740 }
18741
Hoonki Lee27511902013-03-14 18:19:06 -070018742 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018743 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018744 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018745 "%s: TDLS mode is disabled OR not enabled in FW."
18746 MAC_ADDRESS_STR " action %d declined.",
18747 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018748 return -ENOTSUPP;
18749 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018750
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018751 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18752
18753 if( NULL == pHddStaCtx )
18754 {
18755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18756 "%s: HDD station context NULL ",__func__);
18757 return -EINVAL;
18758 }
18759
18760 /* STA should be connected and authenticated
18761 * before sending any TDLS frames
18762 */
18763 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18764 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
18765 {
18766 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18767 "STA is not connected or unauthenticated. "
18768 "connState %u, uIsAuthenticated %u",
18769 pHddStaCtx->conn_info.connState,
18770 pHddStaCtx->conn_info.uIsAuthenticated);
18771 return -EAGAIN;
18772 }
18773
Hoonki Lee27511902013-03-14 18:19:06 -070018774 /* other than teardown frame, other mgmt frames are not sent if disabled */
18775 if (SIR_MAC_TDLS_TEARDOWN != action_code)
18776 {
18777 /* if tdls_mode is disabled to respond to peer's request */
18778 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
18779 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018781 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018782 " TDLS mode is disabled. action %d declined.",
18783 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070018784
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018785 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070018786 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053018787
18788 if (vos_max_concurrent_connections_reached())
18789 {
18790 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
18791 return -EINVAL;
18792 }
Hoonki Lee27511902013-03-14 18:19:06 -070018793 }
18794
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018795 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
18796 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053018797 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018798 {
18799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018800 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018801 " TDLS setup is ongoing. action %d declined.",
18802 __func__, MAC_ADDR_ARRAY(peer), action_code);
18803 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018804 }
18805 }
18806
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018807 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
18808 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080018809 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018810 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18811 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018812 {
18813 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
18814 we return error code at 'add_station()'. Hence we have this
18815 check again in addtion to add_station().
18816 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018817 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018818 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18820 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018821 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
18822 __func__, MAC_ADDR_ARRAY(peer), action_code,
18823 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053018824 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080018825 }
18826 else
18827 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018828 /* maximum reached. tweak to send error code to peer and return
18829 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018830 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18832 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018833 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
18834 __func__, MAC_ADDR_ARRAY(peer), status_code,
18835 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070018836 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018837 /* fall through to send setup resp with failure status
18838 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018839 }
18840 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018841 else
18842 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018843 mutex_lock(&pHddCtx->tdls_lock);
18844 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018845 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018846 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018847 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018849 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
18850 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018851 return -EPERM;
18852 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018853 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018854 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018855 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018856
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018858 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018859 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
18860 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018861
Hoonki Leea34dd892013-02-05 22:56:02 -080018862 /*Except teardown responder will not be used so just make 0*/
18863 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018864 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080018865 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018866
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018867 mutex_lock(&pHddCtx->tdls_lock);
18868 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018869
18870 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
18871 responder = pTdlsPeer->is_responder;
18872 else
Hoonki Leea34dd892013-02-05 22:56:02 -080018873 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018874 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018875 "%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 -070018876 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
18877 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018878 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018879 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080018880 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018881 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018882 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018883
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053018884 /* Discard TDLS setup if peer is removed by user app */
18885 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
18886 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18887 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
18888 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
18889
18890 mutex_lock(&pHddCtx->tdls_lock);
18891 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18892 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
18893 mutex_unlock(&pHddCtx->tdls_lock);
18894 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
18895 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
18896 MAC_ADDR_ARRAY(peer), action_code);
18897 return -EINVAL;
18898 }
18899 mutex_unlock(&pHddCtx->tdls_lock);
18900 }
18901
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018902 /* For explicit trigger of DIS_REQ come out of BMPS for
18903 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070018904 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053018905 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018906 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
18907 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070018908 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018909 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018911 "%s: Sending frame action_code %u.Disable BMPS", __func__,
18912 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018913 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
18914 if (status != VOS_STATUS_SUCCESS) {
18915 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018916 } else {
18917 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018918 }
Hoonki Lee14621352013-04-16 17:51:19 -070018919 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018920 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018921 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018922 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
18923 }
18924 }
Hoonki Lee14621352013-04-16 17:51:19 -070018925 }
18926
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018927 /* make sure doesn't call send_mgmt() while it is pending */
18928 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
18929 {
18930 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018931 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018932 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018933 ret = -EBUSY;
18934 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018935 }
18936
18937 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018938 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
18939
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018940 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
18941 pAdapter->sessionId, peer, action_code, dialog_token,
18942 status_code, peer_capability, (tANI_U8 *)buf, len,
18943 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018944
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018945 if (VOS_STATUS_SUCCESS != status)
18946 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18948 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018949 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018950 ret = -EINVAL;
18951 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018952 }
18953
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18955 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
18956 WAIT_TIME_TDLS_MGMT);
18957
Hoonki Leed37cbb32013-04-20 00:31:14 -070018958 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
18959 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
18960
18961 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018962 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070018963 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070018964 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070018965 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018966 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080018967
18968 if (pHddCtx->isLogpInProgress)
18969 {
18970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18971 "%s: LOGP in Progress. Ignore!!!", __func__);
18972 return -EAGAIN;
18973 }
Abhishek Singh837adf22015-10-01 17:37:37 +053018974 if (rc <= 0)
18975 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
18976 WLAN_LOG_INDICATOR_HOST_DRIVER,
18977 WLAN_LOG_REASON_HDD_TIME_OUT,
18978 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080018979
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018980 ret = -EINVAL;
18981 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018982 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018983 else
18984 {
18985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18986 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
18987 __func__, rc, pAdapter->mgmtTxCompletionStatus);
18988 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018989
Gopichand Nakkala05922802013-03-14 12:23:19 -070018990 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070018991 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018992 ret = max_sta_failed;
18993 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070018994 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018995
Hoonki Leea34dd892013-02-05 22:56:02 -080018996 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
18997 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018998 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018999 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
19000 }
Hoonki Leea34dd892013-02-05 22:56:02 -080019001 }
19002 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
19003 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019004 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019005 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
19006 }
Hoonki Leea34dd892013-02-05 22:56:02 -080019007 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019008
19009 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019010
19011tx_failed:
19012 /* add_station will be called before sending TDLS_SETUP_REQ and
19013 * TDLS_SETUP_RSP and as part of add_station driver will enable
19014 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
19015 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
19016 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
19017 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
19018 */
19019
19020 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19021 (SIR_MAC_TDLS_SETUP_RSP == action_code))
19022 wlan_hdd_tdls_check_bmps(pAdapter);
19023 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019024}
19025
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019026#if TDLS_MGMT_VERSION2
19027static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19028 u8 *peer, u8 action_code, u8 dialog_token,
19029 u16 status_code, u32 peer_capability,
19030 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019031#else /* TDLS_MGMT_VERSION2 */
19032#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19033static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19034 struct net_device *dev,
19035 const u8 *peer, u8 action_code,
19036 u8 dialog_token, u16 status_code,
19037 u32 peer_capability, bool initiator,
19038 const u8 *buf, size_t len)
19039#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19040static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19041 struct net_device *dev,
19042 const u8 *peer, u8 action_code,
19043 u8 dialog_token, u16 status_code,
19044 u32 peer_capability, const u8 *buf,
19045 size_t len)
19046#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19047static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19048 struct net_device *dev,
19049 u8 *peer, u8 action_code,
19050 u8 dialog_token,
19051 u16 status_code, u32 peer_capability,
19052 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019053#else
19054static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19055 u8 *peer, u8 action_code, u8 dialog_token,
19056 u16 status_code, const u8 *buf, size_t len)
19057#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019058#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019059{
19060 int ret;
19061
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019062 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019063#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019064 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19065 dialog_token, status_code,
19066 peer_capability, buf, len);
19067#else /* TDLS_MGMT_VERSION2 */
19068#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
19069 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19070 dialog_token, status_code,
19071 peer_capability, initiator,
19072 buf, len);
19073#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19074 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19075 dialog_token, status_code,
19076 peer_capability, buf, len);
19077#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19078 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19079 dialog_token, status_code,
19080 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019081#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019082 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19083 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019084#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019085#endif
19086 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019087
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019088 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019089}
Atul Mittal115287b2014-07-08 13:26:33 +053019090
19091int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019092#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19093 const u8 *peer,
19094#else
Atul Mittal115287b2014-07-08 13:26:33 +053019095 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019096#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019097 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053019098 cfg80211_exttdls_callback callback)
19099{
19100
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019101 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053019102 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019103 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053019104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19105 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
19106 __func__, MAC_ADDR_ARRAY(peer));
19107
19108 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19109 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19110
19111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019112 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19113 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19114 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019115 return -ENOTSUPP;
19116 }
19117
19118 /* To cater the requirement of establishing the TDLS link
19119 * irrespective of the data traffic , get an entry of TDLS peer.
19120 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019121 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019122 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
19123 if (pTdlsPeer == NULL) {
19124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19125 "%s: peer " MAC_ADDRESS_STR " not existing",
19126 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019127 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019128 return -EINVAL;
19129 }
19130
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019131 /* check FW TDLS Off Channel capability */
19132 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019133 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019134 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019135 {
19136 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
19137 pTdlsPeer->peerParams.global_operating_class =
19138 tdls_peer_params->global_operating_class;
19139 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
19140 pTdlsPeer->peerParams.min_bandwidth_kbps =
19141 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019142 /* check configured channel is valid, non dfs and
19143 * not current operating channel */
19144 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
19145 tdls_peer_params->channel)) &&
19146 (pHddStaCtx) &&
19147 (tdls_peer_params->channel !=
19148 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019149 {
19150 pTdlsPeer->isOffChannelConfigured = TRUE;
19151 }
19152 else
19153 {
19154 pTdlsPeer->isOffChannelConfigured = FALSE;
19155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19156 "%s: Configured Tdls Off Channel is not valid", __func__);
19157
19158 }
19159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019160 "%s: tdls_off_channel %d isOffChannelConfigured %d "
19161 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019162 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019163 pTdlsPeer->isOffChannelConfigured,
19164 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019165 }
19166 else
19167 {
19168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019169 "%s: TDLS off channel FW capability %d, "
19170 "host capab %d or Invalid TDLS Peer Params", __func__,
19171 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
19172 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019173 }
19174
Atul Mittal115287b2014-07-08 13:26:33 +053019175 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
19176
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019177 mutex_unlock(&pHddCtx->tdls_lock);
19178
Atul Mittal115287b2014-07-08 13:26:33 +053019179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19180 " %s TDLS Add Force Peer Failed",
19181 __func__);
19182 return -EINVAL;
19183 }
19184 /*EXT TDLS*/
19185
19186 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019187 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19189 " %s TDLS set callback Failed",
19190 __func__);
19191 return -EINVAL;
19192 }
19193
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019194 mutex_unlock(&pHddCtx->tdls_lock);
19195
Atul Mittal115287b2014-07-08 13:26:33 +053019196 return(0);
19197
19198}
19199
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019200int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
19201#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19202 const u8 *peer
19203#else
19204 u8 *peer
19205#endif
19206)
Atul Mittal115287b2014-07-08 13:26:33 +053019207{
19208
19209 hddTdlsPeer_t *pTdlsPeer;
19210 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019211
Atul Mittal115287b2014-07-08 13:26:33 +053019212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19213 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
19214 __func__, MAC_ADDR_ARRAY(peer));
19215
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019216 if (0 != wlan_hdd_validate_context(pHddCtx)) {
19217 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
19218 return -EINVAL;
19219 }
19220
Atul Mittal115287b2014-07-08 13:26:33 +053019221 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19222 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19223
19224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019225 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19226 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19227 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019228 return -ENOTSUPP;
19229 }
19230
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019231 mutex_lock(&pHddCtx->tdls_lock);
19232 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053019233
19234 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019235 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019236 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019237 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053019238 __func__, MAC_ADDR_ARRAY(peer));
19239 return -EINVAL;
19240 }
19241 else {
19242 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
19243 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019244 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
19245 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019246 /* if channel switch is configured, reset
19247 the channel for this peer */
19248 if (TRUE == pTdlsPeer->isOffChannelConfigured)
19249 {
19250 pTdlsPeer->peerParams.channel = 0;
19251 pTdlsPeer->isOffChannelConfigured = FALSE;
19252 }
Atul Mittal115287b2014-07-08 13:26:33 +053019253 }
19254
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019255 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019256 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019257 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053019258 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019259 }
Atul Mittal115287b2014-07-08 13:26:33 +053019260
19261 /*EXT TDLS*/
19262
19263 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019264 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19266 " %s TDLS set callback Failed",
19267 __func__);
19268 return -EINVAL;
19269 }
Atul Mittal115287b2014-07-08 13:26:33 +053019270
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019271 mutex_unlock(&pHddCtx->tdls_lock);
19272
19273 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053019274}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019275static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019276#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19277 const u8 *peer,
19278#else
19279 u8 *peer,
19280#endif
19281 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019282{
19283 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19284 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019285 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019286 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019287
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019288 ENTER();
19289
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019290 if (!pAdapter) {
19291 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
19292 return -EINVAL;
19293 }
19294
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019295 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19296 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
19297 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019298 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019299 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070019301 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019302 return -EINVAL;
19303 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019304
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019305 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019306 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019307 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019308 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019309 }
19310
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019311
19312 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019313 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019314 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019316 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
19317 "Cannot process TDLS commands",
19318 pHddCtx->cfg_ini->fEnableTDLSSupport,
19319 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019320 return -ENOTSUPP;
19321 }
19322
19323 switch (oper) {
19324 case NL80211_TDLS_ENABLE_LINK:
19325 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019326 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019327 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053019328 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
19329 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053019330 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019331 tANI_U16 numCurrTdlsPeers = 0;
19332 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019333 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019334 tSirMacAddr peerMac;
19335 int channel;
19336 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019337
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19339 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
19340 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019341
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019342 mutex_lock(&pHddCtx->tdls_lock);
19343 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019344 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053019345 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019346 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019347 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19348 " (oper %d) not exsting. ignored",
19349 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19350 return -EINVAL;
19351 }
19352
19353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19354 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19355 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19356 "NL80211_TDLS_ENABLE_LINK");
19357
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019358 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
19359 {
19360 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
19361 MAC_ADDRESS_STR " failed",
19362 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019363 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019364 return -EINVAL;
19365 }
19366
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019367 /* before starting tdls connection, set tdls
19368 * off channel established status to default value */
19369 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019370
19371 mutex_unlock(&pHddCtx->tdls_lock);
19372
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053019373 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019374 /* TDLS Off Channel, Disable tdls channel switch,
19375 when there are more than one tdls link */
19376 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053019377 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019378 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019379 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019380 /* get connected peer and send disable tdls off chan */
19381 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019382 if ((connPeer) &&
19383 (connPeer->isOffChannelSupported == TRUE) &&
19384 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019385 {
19386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19387 "%s: More then one peer connected, Disable "
19388 "TDLS channel switch", __func__);
19389
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019390 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019391 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
19392 channel = connPeer->peerParams.channel;
19393
19394 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019395
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019396 ret = sme_SendTdlsChanSwitchReq(
19397 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019398 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019399 peerMac,
19400 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019401 TDLS_OFF_CHANNEL_BW_OFFSET,
19402 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019403 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019404 hddLog(VOS_TRACE_LEVEL_ERROR,
19405 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019406 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019407 }
19408 else
19409 {
19410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19411 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019412 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019413 "isOffChannelConfigured %d",
19414 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019415 (connPeer ? (connPeer->isOffChannelSupported)
19416 : -1),
19417 (connPeer ? (connPeer->isOffChannelConfigured)
19418 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019419 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019420 }
19421 }
19422
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019423 mutex_lock(&pHddCtx->tdls_lock);
19424 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19425 if ( NULL == pTdlsPeer ) {
19426 mutex_unlock(&pHddCtx->tdls_lock);
19427 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19428 "%s: " MAC_ADDRESS_STR
19429 " (oper %d) peer got freed in other context. ignored",
19430 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19431 return -EINVAL;
19432 }
19433 peer_status = pTdlsPeer->link_status;
19434 mutex_unlock(&pHddCtx->tdls_lock);
19435
19436 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019437 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019438 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053019439
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019440 if (0 != wlan_hdd_tdls_get_link_establish_params(
19441 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019442 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019443 return -EINVAL;
19444 }
19445 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019446
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019447 ret = sme_SendTdlsLinkEstablishParams(
19448 WLAN_HDD_GET_HAL_CTX(pAdapter),
19449 pAdapter->sessionId, peer,
19450 &tdlsLinkEstablishParams);
19451 if (ret != VOS_STATUS_SUCCESS) {
19452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
19453 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019454 /* Send TDLS peer UAPSD capabilities to the firmware and
19455 * register with the TL on after the response for this operation
19456 * is received .
19457 */
19458 ret = wait_for_completion_interruptible_timeout(
19459 &pAdapter->tdls_link_establish_req_comp,
19460 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053019461
19462 mutex_lock(&pHddCtx->tdls_lock);
19463 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19464 if ( NULL == pTdlsPeer ) {
19465 mutex_unlock(&pHddCtx->tdls_lock);
19466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19467 "%s %d: " MAC_ADDRESS_STR
19468 " (oper %d) peer got freed in other context. ignored",
19469 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
19470 (int)oper);
19471 return -EINVAL;
19472 }
19473 peer_status = pTdlsPeer->link_status;
19474 mutex_unlock(&pHddCtx->tdls_lock);
19475
19476 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019477 {
19478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019479 FL("Link Establish Request Failed Status %ld"),
19480 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019481 return -EINVAL;
19482 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019483 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019484
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019485 mutex_lock(&pHddCtx->tdls_lock);
19486 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19487 if ( NULL == pTdlsPeer ) {
19488 mutex_unlock(&pHddCtx->tdls_lock);
19489 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19490 "%s: " MAC_ADDRESS_STR
19491 " (oper %d) peer got freed in other context. ignored",
19492 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19493 return -EINVAL;
19494 }
19495
Atul Mittal115287b2014-07-08 13:26:33 +053019496 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
19497 eTDLS_LINK_CONNECTED,
19498 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019499 staDesc.ucSTAId = pTdlsPeer->staId;
19500 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053019501
19502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19503 "%s: tdlsLinkEstablishParams of peer "
19504 MAC_ADDRESS_STR "uapsdQueues: %d"
19505 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
19506 "isResponder: %d peerstaId: %d",
19507 __func__,
19508 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
19509 tdlsLinkEstablishParams.uapsdQueues,
19510 tdlsLinkEstablishParams.qos,
19511 tdlsLinkEstablishParams.maxSp,
19512 tdlsLinkEstablishParams.isBufSta,
19513 tdlsLinkEstablishParams.isOffChannelSupported,
19514 tdlsLinkEstablishParams.isResponder,
19515 pTdlsPeer->staId);
19516
19517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19518 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
19519 __func__,
19520 staDesc.ucSTAId,
19521 staDesc.ucQosEnabled);
19522
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019523 ret = WLANTL_UpdateTdlsSTAClient(
19524 pHddCtx->pvosContext,
19525 &staDesc);
19526 if (ret != VOS_STATUS_SUCCESS) {
19527 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
19528 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053019529
Gopichand Nakkala471708b2013-06-04 20:03:01 +053019530 /* Mark TDLS client Authenticated .*/
19531 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
19532 pTdlsPeer->staId,
19533 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070019534 if (VOS_STATUS_SUCCESS == status)
19535 {
Hoonki Lee14621352013-04-16 17:51:19 -070019536 if (pTdlsPeer->is_responder == 0)
19537 {
19538 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019539 tdlsConnInfo_t *tdlsInfo;
19540
19541 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
19542
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019543 if (!vos_timer_is_initialized(
19544 &pTdlsPeer->initiatorWaitTimeoutTimer))
19545 {
19546 /* Initialize initiator wait callback */
19547 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019548 &pTdlsPeer->initiatorWaitTimeoutTimer,
19549 VOS_TIMER_TYPE_SW,
19550 wlan_hdd_tdls_initiator_wait_cb,
19551 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019552 }
Hoonki Lee14621352013-04-16 17:51:19 -070019553 wlan_hdd_tdls_timer_restart(pAdapter,
19554 &pTdlsPeer->initiatorWaitTimeoutTimer,
19555 WAIT_TIME_TDLS_INITIATOR);
19556 /* suspend initiator TX until it receives direct packet from the
19557 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019558 ret = WLANTL_SuspendDataTx(
19559 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
19560 &staId, NULL);
19561 if (ret != VOS_STATUS_SUCCESS) {
19562 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
19563 }
Hoonki Lee14621352013-04-16 17:51:19 -070019564 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019565
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019566 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019567 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019568 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019569 suppChannelLen =
19570 tdlsLinkEstablishParams.supportedChannelsLen;
19571
19572 if ((suppChannelLen > 0) &&
19573 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
19574 {
19575 tANI_U8 suppPeerChannel = 0;
19576 int i = 0;
19577 for (i = 0U; i < suppChannelLen; i++)
19578 {
19579 suppPeerChannel =
19580 tdlsLinkEstablishParams.supportedChannels[i];
19581
19582 pTdlsPeer->isOffChannelSupported = FALSE;
19583 if (suppPeerChannel ==
19584 pTdlsPeer->peerParams.channel)
19585 {
19586 pTdlsPeer->isOffChannelSupported = TRUE;
19587 break;
19588 }
19589 }
19590 }
19591 else
19592 {
19593 pTdlsPeer->isOffChannelSupported = FALSE;
19594 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019595 }
19596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19597 "%s: TDLS channel switch request for channel "
19598 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019599 "%d isOffChannelSupported %d", __func__,
19600 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019601 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019602 suppChannelLen,
19603 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019604
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019605 /* TDLS Off Channel, Enable tdls channel switch,
19606 when their is only one tdls link and it supports */
19607 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19608 if ((numCurrTdlsPeers == 1) &&
19609 (TRUE == pTdlsPeer->isOffChannelSupported) &&
19610 (TRUE == pTdlsPeer->isOffChannelConfigured))
19611 {
19612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19613 "%s: Send TDLS channel switch request for channel %d",
19614 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019615
19616 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019617 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
19618 channel = pTdlsPeer->peerParams.channel;
19619
19620 mutex_unlock(&pHddCtx->tdls_lock);
19621
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019622 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
19623 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019624 peerMac,
19625 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019626 TDLS_OFF_CHANNEL_BW_OFFSET,
19627 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019628 if (ret != VOS_STATUS_SUCCESS) {
19629 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
19630 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019631 }
19632 else
19633 {
19634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19635 "%s: TDLS channel switch request not sent"
19636 " numCurrTdlsPeers %d "
19637 "isOffChannelSupported %d "
19638 "isOffChannelConfigured %d",
19639 __func__, numCurrTdlsPeers,
19640 pTdlsPeer->isOffChannelSupported,
19641 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019642 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019643 }
19644
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070019645 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019646 else
19647 mutex_unlock(&pHddCtx->tdls_lock);
19648
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019649 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019650
19651 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019652 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
19653 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019654 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019655 int ac;
19656 uint8 ucAc[4] = { WLANTL_AC_VO,
19657 WLANTL_AC_VI,
19658 WLANTL_AC_BK,
19659 WLANTL_AC_BE };
19660 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
19661 for(ac=0; ac < 4; ac++)
19662 {
19663 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
19664 pTdlsPeer->staId, ucAc[ac],
19665 tlTid[ac], tlTid[ac], 0, 0,
19666 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019667 if (status != VOS_STATUS_SUCCESS) {
19668 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
19669 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019670 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019671 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019672 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019673
Bhargav Shah66896792015-10-01 18:17:37 +053019674 /* stop TCP delack timer if TDLS is enable */
19675 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
19676 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053019677 hdd_wlan_tdls_enable_link_event(peer,
19678 pTdlsPeer->isOffChannelSupported,
19679 pTdlsPeer->isOffChannelConfigured,
19680 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019681 }
19682 break;
19683 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080019684 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019685 tANI_U16 numCurrTdlsPeers = 0;
19686 hddTdlsPeer_t *connPeer = NULL;
19687
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19689 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
19690 __func__, MAC_ADDR_ARRAY(peer));
19691
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019692 mutex_lock(&pHddCtx->tdls_lock);
19693 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019694
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019695
Sunil Dutt41de4e22013-11-14 18:09:02 +053019696 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019697 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019698 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19699 " (oper %d) not exsting. ignored",
19700 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19701 return -EINVAL;
19702 }
19703
19704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19705 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19706 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19707 "NL80211_TDLS_DISABLE_LINK");
19708
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019709 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080019710 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019711 long status;
19712
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019713 /* set tdls off channel status to false for this peer */
19714 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053019715 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
19716 eTDLS_LINK_TEARING,
19717 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
19718 eTDLS_LINK_UNSPECIFIED:
19719 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019720 mutex_unlock(&pHddCtx->tdls_lock);
19721
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019722 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
19723
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019724 status = sme_DeleteTdlsPeerSta(
19725 WLAN_HDD_GET_HAL_CTX(pAdapter),
19726 pAdapter->sessionId, peer );
19727 if (status != VOS_STATUS_SUCCESS) {
19728 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
19729 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019730
19731 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
19732 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019733
19734 mutex_lock(&pHddCtx->tdls_lock);
19735 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19736 if ( NULL == pTdlsPeer ) {
19737 mutex_unlock(&pHddCtx->tdls_lock);
19738 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19739 " peer was freed in other context",
19740 __func__, MAC_ADDR_ARRAY(peer));
19741 return -EINVAL;
19742 }
19743
Atul Mittal271a7652014-09-12 13:18:22 +053019744 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053019745 eTDLS_LINK_IDLE,
19746 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019747 mutex_unlock(&pHddCtx->tdls_lock);
19748
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019749 if (status <= 0)
19750 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19752 "%s: Del station failed status %ld",
19753 __func__, status);
19754 return -EPERM;
19755 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019756
19757 /* TDLS Off Channel, Enable tdls channel switch,
19758 when their is only one tdls link and it supports */
19759 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19760 if (numCurrTdlsPeers == 1)
19761 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019762 tSirMacAddr peerMac;
19763 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019764
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019765 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019766 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019767
19768 if (connPeer == NULL) {
19769 mutex_unlock(&pHddCtx->tdls_lock);
19770 hddLog(VOS_TRACE_LEVEL_ERROR,
19771 "%s connPeer is NULL", __func__);
19772 return -EINVAL;
19773 }
19774
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019775 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
19776 channel = connPeer->peerParams.channel;
19777
19778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19779 "%s: TDLS channel switch "
19780 "isOffChannelSupported %d "
19781 "isOffChannelConfigured %d "
19782 "isOffChannelEstablished %d",
19783 __func__,
19784 (connPeer ? connPeer->isOffChannelSupported : -1),
19785 (connPeer ? connPeer->isOffChannelConfigured : -1),
19786 (connPeer ? connPeer->isOffChannelEstablished : -1));
19787
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019788 if ((connPeer) &&
19789 (connPeer->isOffChannelSupported == TRUE) &&
19790 (connPeer->isOffChannelConfigured == TRUE))
19791 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019792 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019793 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019794 status = sme_SendTdlsChanSwitchReq(
19795 WLAN_HDD_GET_HAL_CTX(pAdapter),
19796 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019797 peerMac,
19798 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019799 TDLS_OFF_CHANNEL_BW_OFFSET,
19800 TDLS_CHANNEL_SWITCH_ENABLE);
19801 if (status != VOS_STATUS_SUCCESS) {
19802 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
19803 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019804 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019805 else
19806 mutex_unlock(&pHddCtx->tdls_lock);
19807 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019808 else
19809 {
19810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19811 "%s: TDLS channel switch request not sent "
19812 "numCurrTdlsPeers %d ",
19813 __func__, numCurrTdlsPeers);
19814 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019815 }
19816 else
19817 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019818 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19820 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080019821 }
Bhargav Shah66896792015-10-01 18:17:37 +053019822 if (numCurrTdlsPeers == 0) {
19823 /* start TCP delack timer if TDLS is disable */
19824 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
19825 hdd_manage_delack_timer(pHddCtx);
19826 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019827 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019828 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019829 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019830 {
Atul Mittal115287b2014-07-08 13:26:33 +053019831 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019832
Atul Mittal115287b2014-07-08 13:26:33 +053019833 if (0 != status)
19834 {
19835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019836 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053019837 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019838 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053019839 break;
19840 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019841 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019842 {
Atul Mittal115287b2014-07-08 13:26:33 +053019843 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
19844 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019845 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053019846 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019847
Atul Mittal115287b2014-07-08 13:26:33 +053019848 if (0 != status)
19849 {
19850 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019851 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053019852 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053019853 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053019854 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019855 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019856 case NL80211_TDLS_DISCOVERY_REQ:
19857 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019858 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019859 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019860 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019861 return -ENOTSUPP;
19862 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019863 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19864 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019865 return -ENOTSUPP;
19866 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019867
19868 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019869 return 0;
19870}
Chilam NG571c65a2013-01-19 12:27:36 +053019871
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019872static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019873#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19874 const u8 *peer,
19875#else
19876 u8 *peer,
19877#endif
19878 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019879{
19880 int ret;
19881
19882 vos_ssr_protect(__func__);
19883 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
19884 vos_ssr_unprotect(__func__);
19885
19886 return ret;
19887}
19888
Chilam NG571c65a2013-01-19 12:27:36 +053019889int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
19890 struct net_device *dev, u8 *peer)
19891{
Arif Hussaina7c8e412013-11-20 11:06:42 -080019892 hddLog(VOS_TRACE_LEVEL_INFO,
19893 "tdls send discover req: "MAC_ADDRESS_STR,
19894 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019895#if TDLS_MGMT_VERSION2
19896 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19897 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19898#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019899#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19900 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19901 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
19902#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19903 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19904 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19905#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19906 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19907 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19908#else
Chilam NG571c65a2013-01-19 12:27:36 +053019909 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19910 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019911#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019912#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053019913}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019914#endif
19915
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019916#ifdef WLAN_FEATURE_GTK_OFFLOAD
19917/*
19918 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
19919 * Callback rountine called upon receiving response for
19920 * get offload info
19921 */
19922void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
19923 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
19924{
19925
19926 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019927 tANI_U8 tempReplayCounter[8];
19928 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019929
19930 ENTER();
19931
19932 if (NULL == pAdapter)
19933 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019934 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019935 "%s: HDD adapter is Null", __func__);
19936 return ;
19937 }
19938
19939 if (NULL == pGtkOffloadGetInfoRsp)
19940 {
19941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19942 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
19943 return ;
19944 }
19945
19946 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
19947 {
19948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19949 "%s: wlan Failed to get replay counter value",
19950 __func__);
19951 return ;
19952 }
19953
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019954 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19955 /* Update replay counter */
19956 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
19957 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19958
19959 {
19960 /* changing from little to big endian since supplicant
19961 * works on big endian format
19962 */
19963 int i;
19964 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19965
19966 for (i = 0; i < 8; i++)
19967 {
19968 tempReplayCounter[7-i] = (tANI_U8)p[i];
19969 }
19970 }
19971
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019972 /* Update replay counter to NL */
19973 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019974 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019975}
19976
19977/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019978 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019979 * This function is used to offload GTK rekeying job to the firmware.
19980 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019981int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019982 struct cfg80211_gtk_rekey_data *data)
19983{
19984 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19985 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19986 hdd_station_ctx_t *pHddStaCtx;
19987 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019988 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019989 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019990 eHalStatus status = eHAL_STATUS_FAILURE;
19991
19992 ENTER();
19993
19994 if (NULL == pAdapter)
19995 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019997 "%s: HDD adapter is Null", __func__);
19998 return -ENODEV;
19999 }
20000
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020001 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20002 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
20003 pAdapter->sessionId, pAdapter->device_mode));
20004
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020005 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020006 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020007 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020008 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020009 }
20010
20011 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20012 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
20013 if (NULL == hHal)
20014 {
20015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20016 "%s: HAL context is Null!!!", __func__);
20017 return -EAGAIN;
20018 }
20019
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020020 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
20021 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
20022 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
20023 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020024 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020025 {
20026 /* changing from big to little endian since driver
20027 * works on little endian format
20028 */
20029 tANI_U8 *p =
20030 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
20031 int i;
20032
20033 for (i = 0; i < 8; i++)
20034 {
20035 p[7-i] = data->replay_ctr[i];
20036 }
20037 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020038
20039 if (TRUE == pHddCtx->hdd_wlan_suspended)
20040 {
20041 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020042 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
20043 sizeof (tSirGtkOffloadParams));
20044 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020045 pAdapter->sessionId);
20046
20047 if (eHAL_STATUS_SUCCESS != status)
20048 {
20049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20050 "%s: sme_SetGTKOffload failed, returned %d",
20051 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020052
20053 /* Need to clear any trace of key value in the memory.
20054 * Thus zero out the memory even though it is local
20055 * variable.
20056 */
20057 vos_mem_zero(&hddGtkOffloadReqParams,
20058 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020059 return status;
20060 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020061 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20062 "%s: sme_SetGTKOffload successfull", __func__);
20063 }
20064 else
20065 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020066 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20067 "%s: wlan not suspended GTKOffload request is stored",
20068 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020069 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020070
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020071 /* Need to clear any trace of key value in the memory.
20072 * Thus zero out the memory even though it is local
20073 * variable.
20074 */
20075 vos_mem_zero(&hddGtkOffloadReqParams,
20076 sizeof(hddGtkOffloadReqParams));
20077
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020078 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020079 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020080}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020081
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020082int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
20083 struct cfg80211_gtk_rekey_data *data)
20084{
20085 int ret;
20086
20087 vos_ssr_protect(__func__);
20088 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
20089 vos_ssr_unprotect(__func__);
20090
20091 return ret;
20092}
20093#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020094/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020095 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020096 * This function is used to set access control policy
20097 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020098static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20099 struct net_device *dev,
20100 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020101{
20102 int i;
20103 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20104 hdd_hostapd_state_t *pHostapdState;
20105 tsap_Config_t *pConfig;
20106 v_CONTEXT_t pVosContext = NULL;
20107 hdd_context_t *pHddCtx;
20108 int status;
20109
20110 ENTER();
20111
20112 if (NULL == pAdapter)
20113 {
20114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20115 "%s: HDD adapter is Null", __func__);
20116 return -ENODEV;
20117 }
20118
20119 if (NULL == params)
20120 {
20121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20122 "%s: params is Null", __func__);
20123 return -EINVAL;
20124 }
20125
20126 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20127 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020128 if (0 != status)
20129 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020130 return status;
20131 }
20132
20133 pVosContext = pHddCtx->pvosContext;
20134 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
20135
20136 if (NULL == pHostapdState)
20137 {
20138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20139 "%s: pHostapdState is Null", __func__);
20140 return -EINVAL;
20141 }
20142
20143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
20144 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020145 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20146 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
20147 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020148
20149 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
20150 {
20151 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
20152
20153 /* default value */
20154 pConfig->num_accept_mac = 0;
20155 pConfig->num_deny_mac = 0;
20156
20157 /**
20158 * access control policy
20159 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
20160 * listed in hostapd.deny file.
20161 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
20162 * listed in hostapd.accept file.
20163 */
20164 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
20165 {
20166 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
20167 }
20168 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
20169 {
20170 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
20171 }
20172 else
20173 {
20174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20175 "%s:Acl Policy : %d is not supported",
20176 __func__, params->acl_policy);
20177 return -ENOTSUPP;
20178 }
20179
20180 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
20181 {
20182 pConfig->num_accept_mac = params->n_acl_entries;
20183 for (i = 0; i < params->n_acl_entries; i++)
20184 {
20185 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20186 "** Add ACL MAC entry %i in WhiletList :"
20187 MAC_ADDRESS_STR, i,
20188 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20189
20190 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
20191 sizeof(qcmacaddr));
20192 }
20193 }
20194 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
20195 {
20196 pConfig->num_deny_mac = params->n_acl_entries;
20197 for (i = 0; i < params->n_acl_entries; i++)
20198 {
20199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20200 "** Add ACL MAC entry %i in BlackList :"
20201 MAC_ADDRESS_STR, i,
20202 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20203
20204 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
20205 sizeof(qcmacaddr));
20206 }
20207 }
20208
20209 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
20210 {
20211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20212 "%s: SAP Set Mac Acl fail", __func__);
20213 return -EINVAL;
20214 }
20215 }
20216 else
20217 {
20218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053020219 "%s: Invalid device_mode = %s (%d)",
20220 __func__, hdd_device_modetoString(pAdapter->device_mode),
20221 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020222 return -EINVAL;
20223 }
20224
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020225 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020226 return 0;
20227}
20228
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020229static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20230 struct net_device *dev,
20231 const struct cfg80211_acl_data *params)
20232{
20233 int ret;
20234 vos_ssr_protect(__func__);
20235 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
20236 vos_ssr_unprotect(__func__);
20237
20238 return ret;
20239}
20240
Leo Chang9056f462013-08-01 19:21:11 -070020241#ifdef WLAN_NL80211_TESTMODE
20242#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070020243void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070020244(
20245 void *pAdapter,
20246 void *indCont
20247)
20248{
Leo Changd9df8aa2013-09-26 13:32:26 -070020249 tSirLPHBInd *lphbInd;
20250 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053020251 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070020252
20253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020254 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070020255
c_hpothu73f35e62014-04-18 13:40:08 +053020256 if (pAdapter == NULL)
20257 {
20258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20259 "%s: pAdapter is NULL\n",__func__);
20260 return;
20261 }
20262
Leo Chang9056f462013-08-01 19:21:11 -070020263 if (NULL == indCont)
20264 {
20265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020266 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070020267 return;
20268 }
20269
c_hpothu73f35e62014-04-18 13:40:08 +053020270 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070020271 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070020272 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053020273 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070020274 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070020275 GFP_ATOMIC);
20276 if (!skb)
20277 {
20278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20279 "LPHB timeout, NL buffer alloc fail");
20280 return;
20281 }
20282
Leo Changac3ba772013-10-07 09:47:04 -070020283 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070020284 {
20285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20286 "WLAN_HDD_TM_ATTR_CMD put fail");
20287 goto nla_put_failure;
20288 }
Leo Changac3ba772013-10-07 09:47:04 -070020289 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070020290 {
20291 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20292 "WLAN_HDD_TM_ATTR_TYPE put fail");
20293 goto nla_put_failure;
20294 }
Leo Changac3ba772013-10-07 09:47:04 -070020295 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070020296 sizeof(tSirLPHBInd), lphbInd))
20297 {
20298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20299 "WLAN_HDD_TM_ATTR_DATA put fail");
20300 goto nla_put_failure;
20301 }
Leo Chang9056f462013-08-01 19:21:11 -070020302 cfg80211_testmode_event(skb, GFP_ATOMIC);
20303 return;
20304
20305nla_put_failure:
20306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20307 "NLA Put fail");
20308 kfree_skb(skb);
20309
20310 return;
20311}
20312#endif /* FEATURE_WLAN_LPHB */
20313
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020314static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070020315{
20316 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
20317 int err = 0;
20318#ifdef FEATURE_WLAN_LPHB
20319 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070020320 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020321
20322 ENTER();
20323
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020324 err = wlan_hdd_validate_context(pHddCtx);
20325 if (0 != err)
20326 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020327 return err;
20328 }
Leo Chang9056f462013-08-01 19:21:11 -070020329#endif /* FEATURE_WLAN_LPHB */
20330
20331 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
20332 if (err)
20333 {
20334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20335 "%s Testmode INV ATTR", __func__);
20336 return err;
20337 }
20338
20339 if (!tb[WLAN_HDD_TM_ATTR_CMD])
20340 {
20341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20342 "%s Testmode INV CMD", __func__);
20343 return -EINVAL;
20344 }
20345
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020346 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20347 TRACE_CODE_HDD_CFG80211_TESTMODE,
20348 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070020349 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
20350 {
20351#ifdef FEATURE_WLAN_LPHB
20352 /* Low Power Heartbeat configuration request */
20353 case WLAN_HDD_TM_CMD_WLAN_HB:
20354 {
20355 int buf_len;
20356 void *buf;
20357 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080020358 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070020359
20360 if (!tb[WLAN_HDD_TM_ATTR_DATA])
20361 {
20362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20363 "%s Testmode INV DATA", __func__);
20364 return -EINVAL;
20365 }
20366
20367 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
20368 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080020369
Manjeet Singh3c577442017-02-10 19:03:38 +053020370 if (buf_len > sizeof(*hb_params)) {
20371 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
20372 buf_len);
20373 return -ERANGE;
20374 }
20375
Amar Singhal05852702014-02-04 14:40:00 -080020376 hb_params_temp =(tSirLPHBReq *)buf;
20377 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
20378 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
20379 return -EINVAL;
20380
Leo Chang9056f462013-08-01 19:21:11 -070020381 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
20382 if (NULL == hb_params)
20383 {
20384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20385 "%s Request Buffer Alloc Fail", __func__);
20386 return -EINVAL;
20387 }
20388
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053020389 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070020390 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070020391 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
20392 hb_params,
20393 wlan_hdd_cfg80211_lphb_ind_handler);
20394 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070020395 {
Leo Changd9df8aa2013-09-26 13:32:26 -070020396 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20397 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070020398 vos_mem_free(hb_params);
20399 }
Leo Chang9056f462013-08-01 19:21:11 -070020400 return 0;
20401 }
20402#endif /* FEATURE_WLAN_LPHB */
20403 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20405 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070020406 return -EOPNOTSUPP;
20407 }
20408
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020409 EXIT();
20410 return err;
Leo Chang9056f462013-08-01 19:21:11 -070020411}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020412
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053020413static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
20414#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
20415 struct wireless_dev *wdev,
20416#endif
20417 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020418{
20419 int ret;
20420
20421 vos_ssr_protect(__func__);
20422 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
20423 vos_ssr_unprotect(__func__);
20424
20425 return ret;
20426}
Leo Chang9056f462013-08-01 19:21:11 -070020427#endif /* CONFIG_NL80211_TESTMODE */
20428
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020429extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020430static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020431 struct net_device *dev,
20432 int idx, struct survey_info *survey)
20433{
20434 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20435 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053020436 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020437 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053020438 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020439 v_S7_t snr,rssi;
20440 int status, i, j, filled = 0;
20441
20442 ENTER();
20443
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020444 if (NULL == pAdapter)
20445 {
20446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20447 "%s: HDD adapter is Null", __func__);
20448 return -ENODEV;
20449 }
20450
20451 if (NULL == wiphy)
20452 {
20453 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20454 "%s: wiphy is Null", __func__);
20455 return -ENODEV;
20456 }
20457
20458 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20459 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020460 if (0 != status)
20461 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020462 return status;
20463 }
20464
Mihir Sheted9072e02013-08-21 17:02:29 +053020465 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20466
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020467 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053020468 0 != pAdapter->survey_idx ||
20469 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020470 {
20471 /* The survey dump ops when implemented completely is expected to
20472 * return a survey of all channels and the ops is called by the
20473 * kernel with incremental values of the argument 'idx' till it
20474 * returns -ENONET. But we can only support the survey for the
20475 * operating channel for now. survey_idx is used to track
20476 * that the ops is called only once and then return -ENONET for
20477 * the next iteration
20478 */
20479 pAdapter->survey_idx = 0;
20480 return -ENONET;
20481 }
20482
Mukul Sharma9d5233b2015-06-11 20:28:20 +053020483 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
20484 {
20485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20486 "%s: Roaming in progress, hence return ", __func__);
20487 return -ENONET;
20488 }
20489
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020490 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
20491
20492 wlan_hdd_get_snr(pAdapter, &snr);
20493 wlan_hdd_get_rssi(pAdapter, &rssi);
20494
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020495 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20496 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
20497 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020498 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
20499 hdd_wlan_get_freq(channel, &freq);
20500
20501
20502 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
20503 {
20504 if (NULL == wiphy->bands[i])
20505 {
20506 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
20507 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
20508 continue;
20509 }
20510
20511 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
20512 {
20513 struct ieee80211_supported_band *band = wiphy->bands[i];
20514
20515 if (band->channels[j].center_freq == (v_U16_t)freq)
20516 {
20517 survey->channel = &band->channels[j];
20518 /* The Rx BDs contain SNR values in dB for the received frames
20519 * while the supplicant expects noise. So we calculate and
20520 * return the value of noise (dBm)
20521 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
20522 */
20523 survey->noise = rssi - snr;
20524 survey->filled = SURVEY_INFO_NOISE_DBM;
20525 filled = 1;
20526 }
20527 }
20528 }
20529
20530 if (filled)
20531 pAdapter->survey_idx = 1;
20532 else
20533 {
20534 pAdapter->survey_idx = 0;
20535 return -ENONET;
20536 }
20537
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020538 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020539 return 0;
20540}
20541
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020542static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
20543 struct net_device *dev,
20544 int idx, struct survey_info *survey)
20545{
20546 int ret;
20547
20548 vos_ssr_protect(__func__);
20549 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
20550 vos_ssr_unprotect(__func__);
20551
20552 return ret;
20553}
20554
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020555/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020556 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020557 * this is called when cfg80211 driver resume
20558 * driver updates latest sched_scan scan result(if any) to cfg80211 database
20559 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020560int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020561{
20562 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
20563 hdd_adapter_t *pAdapter;
20564 hdd_adapter_list_node_t *pAdapterNode, *pNext;
20565 VOS_STATUS status = VOS_STATUS_SUCCESS;
20566
20567 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020568
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020569 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020570 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020571 return 0;
20572 }
20573
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020574 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
20575 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020576
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053020577 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020578 {
20579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20580 "%s: Resume SoftAP", __func__);
20581 hdd_set_wlan_suspend_mode(false);
20582 }
20583
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020584 spin_lock(&pHddCtx->schedScan_lock);
20585 pHddCtx->isWiphySuspended = FALSE;
20586 if (TRUE != pHddCtx->isSchedScanUpdatePending)
20587 {
20588 spin_unlock(&pHddCtx->schedScan_lock);
20589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20590 "%s: Return resume is not due to PNO indication", __func__);
20591 return 0;
20592 }
20593 // Reset flag to avoid updatating cfg80211 data old results again
20594 pHddCtx->isSchedScanUpdatePending = FALSE;
20595 spin_unlock(&pHddCtx->schedScan_lock);
20596
20597 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
20598
20599 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
20600 {
20601 pAdapter = pAdapterNode->pAdapter;
20602 if ( (NULL != pAdapter) &&
20603 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
20604 {
20605 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020606 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
20608 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020609 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020610 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020611 {
20612 /* Acquire wakelock to handle the case where APP's tries to
20613 * suspend immediately after updating the scan results. Whis
20614 * results in app's is in suspended state and not able to
20615 * process the connect request to AP
20616 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053020617 hdd_prevent_suspend_timeout(2000,
20618 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020619 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020620 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020621
20622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20623 "%s : cfg80211 scan result database updated", __func__);
20624
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020625 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020626 return 0;
20627
20628 }
20629 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
20630 pAdapterNode = pNext;
20631 }
20632
20633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20634 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020635 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020636 return 0;
20637}
20638
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020639int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
20640{
20641 int ret;
20642
20643 vos_ssr_protect(__func__);
20644 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
20645 vos_ssr_unprotect(__func__);
20646
20647 return ret;
20648}
20649
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020650/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020651 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020652 * this is called when cfg80211 driver suspends
20653 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020654int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020655 struct cfg80211_wowlan *wow)
20656{
20657 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020658 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020659
20660 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020661
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020662 ret = wlan_hdd_validate_context(pHddCtx);
20663 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020664 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020665 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020666 }
20667
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053020668 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20670 "%s: Suspend SoftAP", __func__);
20671 hdd_set_wlan_suspend_mode(true);
20672 }
20673
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020674
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020675 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20676 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
20677 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020678 pHddCtx->isWiphySuspended = TRUE;
20679
20680 EXIT();
20681
20682 return 0;
20683}
20684
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020685int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
20686 struct cfg80211_wowlan *wow)
20687{
20688 int ret;
20689
20690 vos_ssr_protect(__func__);
20691 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
20692 vos_ssr_unprotect(__func__);
20693
20694 return ret;
20695}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020696
20697#ifdef FEATURE_OEM_DATA_SUPPORT
20698static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020699 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020700{
20701 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
20702
20703 ENTER();
20704
20705 if (wlan_hdd_validate_context(pHddCtx)) {
20706 return;
20707 }
20708 if (!pMsg)
20709 {
20710 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
20711 return;
20712 }
20713
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020714 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020715
20716 EXIT();
20717 return;
20718
20719}
20720
20721void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020722 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020723{
20724 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
20725
20726 ENTER();
20727
20728 if (wlan_hdd_validate_context(pHddCtx)) {
20729 return;
20730 }
20731
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020732 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020733
20734 switch(evType) {
20735 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020736 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020737 break;
20738 default:
20739 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
20740 break;
20741 }
20742 EXIT();
20743}
20744#endif
20745
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020746#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20747 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020748/**
20749 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
20750 * @wiphy: Pointer to wiphy
20751 * @wdev: Pointer to wireless device structure
20752 *
20753 * This function is used to abort an ongoing scan
20754 *
20755 * Return: None
20756 */
20757static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20758 struct wireless_dev *wdev)
20759{
20760 struct net_device *dev = wdev->netdev;
20761 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
20762 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
20763 int ret;
20764
20765 ENTER();
20766
20767 if (NULL == adapter) {
20768 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
20769 return;
20770 }
20771
20772 ret = wlan_hdd_validate_context(hdd_ctx);
20773 if (0 != ret)
20774 return;
20775
20776 wlan_hdd_scan_abort(adapter);
20777
20778 return;
20779}
20780
20781/**
20782 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
20783 * @wiphy: Pointer to wiphy
20784 * @wdev: Pointer to wireless device structure
20785 *
20786 * Return: None
20787 */
20788void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20789 struct wireless_dev *wdev)
20790{
20791 vos_ssr_protect(__func__);
20792 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
20793 vos_ssr_unprotect(__func__);
20794
20795 return;
20796}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020797#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020798
Abhishek Singh936c6932017-11-07 17:28:23 +053020799#ifdef CHANNEL_SWITCH_SUPPORTED
20800/**
20801 * __wlan_hdd_cfg80211_channel_switch()- function to switch
20802 * channel in SAP/GO
20803 * @wiphy: wiphy pointer
20804 * @dev: dev pointer.
20805 * @csa_params: Change channel params
20806 *
20807 * This function is called to switch channel in SAP/GO
20808 *
20809 * Return: 0 if success else return non zero
20810 */
20811static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
20812 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
20813{
20814 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
20815 hdd_context_t *hdd_ctx;
20816 uint8_t channel;
20817 int ret;
20818 v_CONTEXT_t vos_ctx;
20819
20820 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
20821
20822 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
20823 ret = wlan_hdd_validate_context(hdd_ctx);
20824 if (ret)
20825 return ret;
20826
20827 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
20828 if (!vos_ctx) {
20829 hddLog(LOGE, FL("Vos ctx is null"));
20830 return -EINVAL;
20831 }
20832
20833 if ((WLAN_HDD_SOFTAP != adapter->device_mode) &&
20834 (WLAN_HDD_P2P_GO != adapter->device_mode))
20835 return -ENOTSUPP;
20836
20837 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053020838 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053020839
20840 return ret;
20841}
20842
20843/**
20844 * wlan_hdd_cfg80211_channel_switch()- function to switch
20845 * channel in SAP/GO
20846 * @wiphy: wiphy pointer
20847 * @dev: dev pointer.
20848 * @csa_params: Change channel params
20849 *
20850 * This function is called to switch channel in SAP/GO
20851 *
20852 * Return: 0 if success else return non zero
20853 */
20854static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
20855 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
20856{
20857 int ret;
20858
20859 vos_ssr_protect(__func__);
20860 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
20861 vos_ssr_unprotect(__func__);
20862
20863 return ret;
20864}
20865#endif
20866
Jeff Johnson295189b2012-06-20 16:38:30 -070020867/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020868static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070020869{
20870 .add_virtual_intf = wlan_hdd_add_virtual_intf,
20871 .del_virtual_intf = wlan_hdd_del_virtual_intf,
20872 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
20873 .change_station = wlan_hdd_change_station,
20874#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
20875 .add_beacon = wlan_hdd_cfg80211_add_beacon,
20876 .del_beacon = wlan_hdd_cfg80211_del_beacon,
20877 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020878#else
20879 .start_ap = wlan_hdd_cfg80211_start_ap,
20880 .change_beacon = wlan_hdd_cfg80211_change_beacon,
20881 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070020882#endif
20883 .change_bss = wlan_hdd_cfg80211_change_bss,
20884 .add_key = wlan_hdd_cfg80211_add_key,
20885 .get_key = wlan_hdd_cfg80211_get_key,
20886 .del_key = wlan_hdd_cfg80211_del_key,
20887 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020888#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070020889 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020890#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020891 .scan = wlan_hdd_cfg80211_scan,
20892 .connect = wlan_hdd_cfg80211_connect,
20893 .disconnect = wlan_hdd_cfg80211_disconnect,
20894 .join_ibss = wlan_hdd_cfg80211_join_ibss,
20895 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
20896 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
20897 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
20898 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070020899 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
20900 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053020901 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070020902#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
20903 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
20904 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
20905 .set_txq_params = wlan_hdd_set_txq_params,
20906#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020907 .get_station = wlan_hdd_cfg80211_get_station,
20908 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
20909 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020910 .add_station = wlan_hdd_cfg80211_add_station,
20911#ifdef FEATURE_WLAN_LFR
20912 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
20913 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
20914 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
20915#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070020916#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
20917 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
20918#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020919#ifdef FEATURE_WLAN_TDLS
20920 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
20921 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
20922#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020923#ifdef WLAN_FEATURE_GTK_OFFLOAD
20924 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
20925#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020926#ifdef FEATURE_WLAN_SCAN_PNO
20927 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
20928 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
20929#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020930 .resume = wlan_hdd_cfg80211_resume_wlan,
20931 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020932 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070020933#ifdef WLAN_NL80211_TESTMODE
20934 .testmode_cmd = wlan_hdd_cfg80211_testmode,
20935#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020936 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020937#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20938 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020939 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020940#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053020941#ifdef CHANNEL_SWITCH_SUPPORTED
20942 .channel_switch = wlan_hdd_cfg80211_channel_switch,
20943#endif
20944
Jeff Johnson295189b2012-06-20 16:38:30 -070020945};
20946