blob: b1402b976b30d964a18a27b3084c7f192c0e059f [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
783
Sunil Duttc69bccb2014-05-26 21:30:20 +0530784#ifdef WLAN_FEATURE_LINK_LAYER_STATS
785
786static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
787 struct sk_buff *vendor_event)
788{
789 if (nla_put_u8(vendor_event,
790 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
791 stats->rate.preamble) ||
792 nla_put_u8(vendor_event,
793 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
794 stats->rate.nss) ||
795 nla_put_u8(vendor_event,
796 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
797 stats->rate.bw) ||
798 nla_put_u8(vendor_event,
799 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
800 stats->rate.rateMcsIdx) ||
801 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
802 stats->rate.bitrate ) ||
803 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
804 stats->txMpdu ) ||
805 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
806 stats->rxMpdu ) ||
807 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
808 stats->mpduLost ) ||
809 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
810 stats->retries) ||
811 nla_put_u32(vendor_event,
812 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
813 stats->retriesShort ) ||
814 nla_put_u32(vendor_event,
815 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
816 stats->retriesLong))
817 {
818 hddLog(VOS_TRACE_LEVEL_ERROR,
819 FL("QCA_WLAN_VENDOR_ATTR put fail"));
820 return FALSE;
821 }
822 return TRUE;
823}
824
825static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
826 struct sk_buff *vendor_event)
827{
828 u32 i = 0;
829 struct nlattr *rateInfo;
830 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
831 stats->type) ||
832 nla_put(vendor_event,
833 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
834 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
835 nla_put_u32(vendor_event,
836 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
837 stats->capabilities) ||
838 nla_put_u32(vendor_event,
839 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
840 stats->numRate))
841 {
842 hddLog(VOS_TRACE_LEVEL_ERROR,
843 FL("QCA_WLAN_VENDOR_ATTR put fail"));
844 goto error;
845 }
846
847 rateInfo = nla_nest_start(vendor_event,
848 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530849 if(!rateInfo)
850 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530851 for (i = 0; i < stats->numRate; i++)
852 {
853 struct nlattr *rates;
854 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
855 stats->rateStats +
856 (i * sizeof(tSirWifiRateStat)));
857 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530858 if(!rates)
859 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530860
861 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
862 {
863 hddLog(VOS_TRACE_LEVEL_ERROR,
864 FL("QCA_WLAN_VENDOR_ATTR put fail"));
865 return FALSE;
866 }
867 nla_nest_end(vendor_event, rates);
868 }
869 nla_nest_end(vendor_event, rateInfo);
870
871 return TRUE;
872error:
873 return FALSE;
874}
875
876static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
877 struct sk_buff *vendor_event)
878{
879 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
880 stats->ac ) ||
881 nla_put_u32(vendor_event,
882 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
883 stats->txMpdu ) ||
884 nla_put_u32(vendor_event,
885 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
886 stats->rxMpdu ) ||
887 nla_put_u32(vendor_event,
888 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
889 stats->txMcast ) ||
890 nla_put_u32(vendor_event,
891 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
892 stats->rxMcast ) ||
893 nla_put_u32(vendor_event,
894 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
895 stats->rxAmpdu ) ||
896 nla_put_u32(vendor_event,
897 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
898 stats->txAmpdu ) ||
899 nla_put_u32(vendor_event,
900 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
901 stats->mpduLost )||
902 nla_put_u32(vendor_event,
903 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
904 stats->retries ) ||
905 nla_put_u32(vendor_event,
906 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
907 stats->retriesShort ) ||
908 nla_put_u32(vendor_event,
909 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
910 stats->retriesLong ) ||
911 nla_put_u32(vendor_event,
912 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
913 stats->contentionTimeMin ) ||
914 nla_put_u32(vendor_event,
915 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
916 stats->contentionTimeMax ) ||
917 nla_put_u32(vendor_event,
918 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
919 stats->contentionTimeAvg ) ||
920 nla_put_u32(vendor_event,
921 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
922 stats->contentionNumSamples ))
923 {
924 hddLog(VOS_TRACE_LEVEL_ERROR,
925 FL("QCA_WLAN_VENDOR_ATTR put fail") );
926 return FALSE;
927 }
928 return TRUE;
929}
930
931static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
932 struct sk_buff *vendor_event)
933{
Dino Myclec8f3f332014-07-21 16:48:27 +0530934 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530935 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
936 nla_put(vendor_event,
937 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
938 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
939 nla_put_u32(vendor_event,
940 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
941 stats->state ) ||
942 nla_put_u32(vendor_event,
943 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
944 stats->roaming ) ||
945 nla_put_u32(vendor_event,
946 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
947 stats->capabilities ) ||
948 nla_put(vendor_event,
949 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
950 strlen(stats->ssid), stats->ssid) ||
951 nla_put(vendor_event,
952 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
953 WNI_CFG_BSSID_LEN, stats->bssid) ||
954 nla_put(vendor_event,
955 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
956 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
957 nla_put(vendor_event,
958 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
959 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
960 )
961 {
962 hddLog(VOS_TRACE_LEVEL_ERROR,
963 FL("QCA_WLAN_VENDOR_ATTR put fail") );
964 return FALSE;
965 }
966 return TRUE;
967}
968
Dino Mycle3b9536d2014-07-09 22:05:24 +0530969static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
970 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530971 struct sk_buff *vendor_event)
972{
973 int i = 0;
974 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530975 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
976 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530977 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530978
Sunil Duttc69bccb2014-05-26 21:30:20 +0530979 if (FALSE == put_wifi_interface_info(
980 &pWifiIfaceStat->info,
981 vendor_event))
982 {
983 hddLog(VOS_TRACE_LEVEL_ERROR,
984 FL("QCA_WLAN_VENDOR_ATTR put fail") );
985 return FALSE;
986
987 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530988 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
989 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
990 if (NULL == pWifiIfaceStatTL)
991 {
992 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
993 return FALSE;
994 }
995
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530996 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
997 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
998 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
999 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1000
1001 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1002 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1003 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1004 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301005
1006 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1007 {
1008 if (VOS_STATUS_SUCCESS ==
1009 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1010 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1011 {
1012 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1013 * obtained from TL structure
1014 */
1015
1016 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1017 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301018 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1019
Srinivas Dasari98947432014-11-07 19:41:24 +05301020 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1021 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1022 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1023 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1024 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1025 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1026 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1027 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301028
Srinivas Dasari98947432014-11-07 19:41:24 +05301029 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1030 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1031 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1032 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1033 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1034 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1035 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1036 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301037
Srinivas Dasari98947432014-11-07 19:41:24 +05301038 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1039 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1040 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1041 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1042 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1043 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1044 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1045 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301046 }
1047 else
1048 {
1049 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1050 }
1051
Dino Mycle3b9536d2014-07-09 22:05:24 +05301052 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1053 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1054 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1055 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1056 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1057 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1058 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1059 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1060 }
1061 else
1062 {
1063 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1064 }
1065
1066
Sunil Duttc69bccb2014-05-26 21:30:20 +05301067
1068 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301069 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1070 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1071 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301072 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1073 pWifiIfaceStat->beaconRx) ||
1074 nla_put_u32(vendor_event,
1075 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1076 pWifiIfaceStat->mgmtRx) ||
1077 nla_put_u32(vendor_event,
1078 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1079 pWifiIfaceStat->mgmtActionRx) ||
1080 nla_put_u32(vendor_event,
1081 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1082 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301083 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301084 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1085 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301086 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301087 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1088 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301089 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301090 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1091 pWifiIfaceStat->rssiAck))
1092 {
1093 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301094 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1095 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301096 return FALSE;
1097 }
1098
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301099#ifdef FEATURE_EXT_LL_STAT
1100 /*
1101 * Ensure when EXT_LL_STAT is supported by both host and fwr,
1102 * then host should send Leaky AP stats to upper layer,
1103 * otherwise no need to send these stats.
1104 */
1105 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
1106 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
1107 )
1108 {
1109 hddLog(VOS_TRACE_LEVEL_INFO,
1110 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
1111 pWifiIfaceStat->leakyApStat.is_leaky_ap,
1112 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
1113 pWifiIfaceStat->leakyApStat.rx_leak_window,
1114 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
1115 if (nla_put_u32(vendor_event,
1116 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
1117 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
1118 nla_put_u32(vendor_event,
1119 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
1120 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
1121 nla_put_u32(vendor_event,
1122 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
1123 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
1124 nla_put_u64(vendor_event,
1125 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
1126 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
1127 {
1128 hddLog(VOS_TRACE_LEVEL_ERROR,
1129 FL("EXT_LL_STAT put fail"));
1130 vos_mem_free(pWifiIfaceStatTL);
1131 return FALSE;
1132 }
1133 }
1134#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301135 wmmInfo = nla_nest_start(vendor_event,
1136 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301137 if(!wmmInfo)
1138 {
1139 vos_mem_free(pWifiIfaceStatTL);
1140 return FALSE;
1141 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301142 for (i = 0; i < WIFI_AC_MAX; i++)
1143 {
1144 struct nlattr *wmmStats;
1145 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301146 if(!wmmStats)
1147 {
1148 vos_mem_free(pWifiIfaceStatTL);
1149 return FALSE;
1150 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301151 if (FALSE == put_wifi_wmm_ac_stat(
1152 &pWifiIfaceStat->AccessclassStats[i],
1153 vendor_event))
1154 {
1155 hddLog(VOS_TRACE_LEVEL_ERROR,
1156 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301157 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301158 return FALSE;
1159 }
1160
1161 nla_nest_end(vendor_event, wmmStats);
1162 }
1163 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301164 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301165 return TRUE;
1166}
1167
1168static tSirWifiInterfaceMode
1169 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1170{
1171 switch (deviceMode)
1172 {
1173 case WLAN_HDD_INFRA_STATION:
1174 return WIFI_INTERFACE_STA;
1175 case WLAN_HDD_SOFTAP:
1176 return WIFI_INTERFACE_SOFTAP;
1177 case WLAN_HDD_P2P_CLIENT:
1178 return WIFI_INTERFACE_P2P_CLIENT;
1179 case WLAN_HDD_P2P_GO:
1180 return WIFI_INTERFACE_P2P_GO;
1181 case WLAN_HDD_IBSS:
1182 return WIFI_INTERFACE_IBSS;
1183 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301184 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301185 }
1186}
1187
1188static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1189 tpSirWifiInterfaceInfo pInfo)
1190{
1191 v_U8_t *staMac = NULL;
1192 hdd_station_ctx_t *pHddStaCtx;
1193 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1194 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1195
1196 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1197
1198 vos_mem_copy(pInfo->macAddr,
1199 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1200
1201 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1202 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1203 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1204 {
1205 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1206 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1207 {
1208 pInfo->state = WIFI_DISCONNECTED;
1209 }
1210 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1211 {
1212 hddLog(VOS_TRACE_LEVEL_ERROR,
1213 "%s: Session ID %d, Connection is in progress", __func__,
1214 pAdapter->sessionId);
1215 pInfo->state = WIFI_ASSOCIATING;
1216 }
1217 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1218 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1219 {
1220 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1221 hddLog(VOS_TRACE_LEVEL_ERROR,
1222 "%s: client " MAC_ADDRESS_STR
1223 " is in the middle of WPS/EAPOL exchange.", __func__,
1224 MAC_ADDR_ARRAY(staMac));
1225 pInfo->state = WIFI_AUTHENTICATING;
1226 }
1227 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1228 {
1229 pInfo->state = WIFI_ASSOCIATED;
1230 vos_mem_copy(pInfo->bssid,
1231 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1232 vos_mem_copy(pInfo->ssid,
1233 pHddStaCtx->conn_info.SSID.SSID.ssId,
1234 pHddStaCtx->conn_info.SSID.SSID.length);
1235 //NULL Terminate the string.
1236 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1237 }
1238 }
1239 vos_mem_copy(pInfo->countryStr,
1240 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1241
1242 vos_mem_copy(pInfo->apCountryStr,
1243 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1244
1245 return TRUE;
1246}
1247
1248/*
1249 * hdd_link_layer_process_peer_stats () - This function is called after
1250 * receiving Link Layer Peer statistics from FW.This function converts
1251 * the firmware data to the NL data and sends the same to the kernel/upper
1252 * layers.
1253 */
1254static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1255 v_VOID_t *pData)
1256{
1257 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301258 tpSirWifiPeerStat pWifiPeerStat;
1259 tpSirWifiPeerInfo pWifiPeerInfo;
1260 struct nlattr *peerInfo;
1261 struct sk_buff *vendor_event;
1262 int status, i;
1263
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301264 ENTER();
1265
Sunil Duttc69bccb2014-05-26 21:30:20 +05301266 status = wlan_hdd_validate_context(pHddCtx);
1267 if (0 != status)
1268 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301269 return;
1270 }
1271
1272 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1273
1274 hddLog(VOS_TRACE_LEVEL_INFO,
1275 "LL_STATS_PEER_ALL : numPeers %u",
1276 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301277 /*
1278 * Allocate a size of 4096 for the peer stats comprising
1279 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1280 * sizeof (tSirWifiRateStat).Each field is put with an
1281 * NL attribute.The size of 4096 is considered assuming
1282 * that number of rates shall not exceed beyond 50 with
1283 * the sizeof (tSirWifiRateStat) being 32.
1284 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301285 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1286 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301287 if (!vendor_event)
1288 {
1289 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301290 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301291 __func__);
1292 return;
1293 }
1294 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301295 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1296 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1297 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301298 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1299 pWifiPeerStat->numPeers))
1300 {
1301 hddLog(VOS_TRACE_LEVEL_ERROR,
1302 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1303 kfree_skb(vendor_event);
1304 return;
1305 }
1306
1307 peerInfo = nla_nest_start(vendor_event,
1308 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301309 if(!peerInfo)
1310 {
1311 hddLog(VOS_TRACE_LEVEL_ERROR,
1312 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1313 __func__);
1314 kfree_skb(vendor_event);
1315 return;
1316 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301317
1318 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1319 pWifiPeerStat->peerInfo);
1320
1321 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1322 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301323 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301324 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301325
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301326 if(!peers)
1327 {
1328 hddLog(VOS_TRACE_LEVEL_ERROR,
1329 "%s: peer stats put fail",
1330 __func__);
1331 kfree_skb(vendor_event);
1332 return;
1333 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301334 if (FALSE == put_wifi_peer_info(
1335 pWifiPeerInfo, vendor_event))
1336 {
1337 hddLog(VOS_TRACE_LEVEL_ERROR,
1338 "%s: put_wifi_peer_info put fail", __func__);
1339 kfree_skb(vendor_event);
1340 return;
1341 }
1342
1343 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1344 pWifiPeerStat->peerInfo +
1345 (i * sizeof(tSirWifiPeerInfo)) +
1346 (numRate * sizeof (tSirWifiRateStat)));
1347 nla_nest_end(vendor_event, peers);
1348 }
1349 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301350 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301351 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301352}
1353
1354/*
1355 * hdd_link_layer_process_iface_stats () - This function is called after
1356 * receiving Link Layer Interface statistics from FW.This function converts
1357 * the firmware data to the NL data and sends the same to the kernel/upper
1358 * layers.
1359 */
1360static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1361 v_VOID_t *pData)
1362{
1363 tpSirWifiIfaceStat pWifiIfaceStat;
1364 struct sk_buff *vendor_event;
1365 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1366 int status;
1367
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301368 ENTER();
1369
Sunil Duttc69bccb2014-05-26 21:30:20 +05301370 status = wlan_hdd_validate_context(pHddCtx);
1371 if (0 != status)
1372 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301373 return;
1374 }
1375 /*
1376 * Allocate a size of 4096 for the interface stats comprising
1377 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1378 * assuming that all these fit with in the limit.Please take
1379 * a call on the limit based on the data requirements on
1380 * interface statistics.
1381 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301382 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1383 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301384 if (!vendor_event)
1385 {
1386 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301387 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301388 return;
1389 }
1390
1391 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1392
Dino Mycle3b9536d2014-07-09 22:05:24 +05301393
1394 if (FALSE == hdd_get_interface_info( pAdapter,
1395 &pWifiIfaceStat->info))
1396 {
1397 hddLog(VOS_TRACE_LEVEL_ERROR,
1398 FL("hdd_get_interface_info get fail") );
1399 kfree_skb(vendor_event);
1400 return;
1401 }
1402
1403 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1404 vendor_event))
1405 {
1406 hddLog(VOS_TRACE_LEVEL_ERROR,
1407 FL("put_wifi_iface_stats fail") );
1408 kfree_skb(vendor_event);
1409 return;
1410 }
1411
Sunil Duttc69bccb2014-05-26 21:30:20 +05301412 hddLog(VOS_TRACE_LEVEL_INFO,
1413 "WMI_LINK_STATS_IFACE Data");
1414
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301415 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301416
1417 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301418}
1419
1420/*
1421 * hdd_link_layer_process_radio_stats () - This function is called after
1422 * receiving Link Layer Radio statistics from FW.This function converts
1423 * the firmware data to the NL data and sends the same to the kernel/upper
1424 * layers.
1425 */
1426static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1427 v_VOID_t *pData)
1428{
1429 int status, i;
1430 tpSirWifiRadioStat pWifiRadioStat;
1431 tpSirWifiChannelStats pWifiChannelStats;
1432 struct sk_buff *vendor_event;
1433 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1434 struct nlattr *chList;
1435
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301436 ENTER();
1437
Sunil Duttc69bccb2014-05-26 21:30:20 +05301438 status = wlan_hdd_validate_context(pHddCtx);
1439 if (0 != status)
1440 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301441 return;
1442 }
1443 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1444
1445 hddLog(VOS_TRACE_LEVEL_INFO,
1446 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301447 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05301448 " radio is %d onTime is %u "
1449 " txTime is %u rxTime is %u "
1450 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301451 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301452 " onTimePnoScan is %u onTimeHs20 is %u "
1453 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301454 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301455 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1456 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1457 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301458 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301459 pWifiRadioStat->onTimeRoamScan,
1460 pWifiRadioStat->onTimePnoScan,
1461 pWifiRadioStat->onTimeHs20,
1462 pWifiRadioStat->numChannels);
1463 /*
1464 * Allocate a size of 4096 for the Radio stats comprising
1465 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1466 * (tSirWifiChannelStats).Each channel data is put with an
1467 * NL attribute.The size of 4096 is considered assuming that
1468 * number of channels shall not exceed beyond 60 with the
1469 * sizeof (tSirWifiChannelStats) being 24 bytes.
1470 */
1471
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301472 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1473 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301474 if (!vendor_event)
1475 {
1476 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301477 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301478 return;
1479 }
1480
1481 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301482 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1483 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1484 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301485 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1486 pWifiRadioStat->radio) ||
1487 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301488 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
1489 NUM_RADIOS) ||
1490 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301491 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1492 pWifiRadioStat->onTime) ||
1493 nla_put_u32(vendor_event,
1494 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1495 pWifiRadioStat->txTime) ||
1496 nla_put_u32(vendor_event,
1497 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1498 pWifiRadioStat->rxTime) ||
1499 nla_put_u32(vendor_event,
1500 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1501 pWifiRadioStat->onTimeScan) ||
1502 nla_put_u32(vendor_event,
1503 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1504 pWifiRadioStat->onTimeNbd) ||
1505 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301506 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1507 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301508 nla_put_u32(vendor_event,
1509 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1510 pWifiRadioStat->onTimeRoamScan) ||
1511 nla_put_u32(vendor_event,
1512 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1513 pWifiRadioStat->onTimePnoScan) ||
1514 nla_put_u32(vendor_event,
1515 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1516 pWifiRadioStat->onTimeHs20) ||
1517 nla_put_u32(vendor_event,
1518 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1519 pWifiRadioStat->numChannels))
1520 {
1521 hddLog(VOS_TRACE_LEVEL_ERROR,
1522 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1523 kfree_skb(vendor_event);
1524 return ;
1525 }
1526
1527 chList = nla_nest_start(vendor_event,
1528 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301529 if(!chList)
1530 {
1531 hddLog(VOS_TRACE_LEVEL_ERROR,
1532 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1533 __func__);
1534 kfree_skb(vendor_event);
1535 return;
1536 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301537 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1538 {
1539 struct nlattr *chInfo;
1540
1541 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1542 pWifiRadioStat->channels +
1543 (i * sizeof(tSirWifiChannelStats)));
1544
Sunil Duttc69bccb2014-05-26 21:30:20 +05301545 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301546 if(!chInfo)
1547 {
1548 hddLog(VOS_TRACE_LEVEL_ERROR,
1549 "%s: failed to put chInfo",
1550 __func__);
1551 kfree_skb(vendor_event);
1552 return;
1553 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301554
1555 if (nla_put_u32(vendor_event,
1556 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1557 pWifiChannelStats->channel.width) ||
1558 nla_put_u32(vendor_event,
1559 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1560 pWifiChannelStats->channel.centerFreq) ||
1561 nla_put_u32(vendor_event,
1562 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1563 pWifiChannelStats->channel.centerFreq0) ||
1564 nla_put_u32(vendor_event,
1565 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1566 pWifiChannelStats->channel.centerFreq1) ||
1567 nla_put_u32(vendor_event,
1568 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1569 pWifiChannelStats->onTime) ||
1570 nla_put_u32(vendor_event,
1571 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1572 pWifiChannelStats->ccaBusyTime))
1573 {
1574 hddLog(VOS_TRACE_LEVEL_ERROR,
1575 FL("cfg80211_vendor_event_alloc failed") );
1576 kfree_skb(vendor_event);
1577 return ;
1578 }
1579 nla_nest_end(vendor_event, chInfo);
1580 }
1581 nla_nest_end(vendor_event, chList);
1582
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301583 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301584
1585 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301586 return;
1587}
1588
1589/*
1590 * hdd_link_layer_stats_ind_callback () - This function is called after
1591 * receiving Link Layer indications from FW.This callback converts the firmware
1592 * data to the NL data and send the same to the kernel/upper layers.
1593 */
1594static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1595 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301596 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301597{
Dino Mycled3d50022014-07-07 12:58:25 +05301598 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1599 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301600 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301601 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301602 int status;
1603
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301604 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301605
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301606 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301607 if (0 != status)
1608 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301609 return;
1610 }
1611
Dino Mycled3d50022014-07-07 12:58:25 +05301612 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1613 if (NULL == pAdapter)
1614 {
1615 hddLog(VOS_TRACE_LEVEL_ERROR,
1616 FL(" MAC address %pM does not exist with host"),
1617 macAddr);
1618 return;
1619 }
1620
Sunil Duttc69bccb2014-05-26 21:30:20 +05301621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301622 "%s: Interface: %s LLStats indType: %d", __func__,
1623 pAdapter->dev->name, indType);
1624
Sunil Duttc69bccb2014-05-26 21:30:20 +05301625 switch (indType)
1626 {
1627 case SIR_HAL_LL_STATS_RESULTS_RSP:
1628 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301629 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301630 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1631 "respId = %u, moreResultToFollow = %u",
1632 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1633 macAddr, linkLayerStatsResults->respId,
1634 linkLayerStatsResults->moreResultToFollow);
1635
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301636 spin_lock(&hdd_context_lock);
1637 context = &pHddCtx->ll_stats_context;
1638 /* validate response received from target */
1639 if ((context->request_id != linkLayerStatsResults->respId) ||
1640 !(context->request_bitmap & linkLayerStatsResults->paramId))
1641 {
1642 spin_unlock(&hdd_context_lock);
1643 hddLog(LOGE,
1644 FL("Error : Request id %d response id %d request bitmap 0x%x"
1645 "response bitmap 0x%x"),
1646 context->request_id, linkLayerStatsResults->respId,
1647 context->request_bitmap, linkLayerStatsResults->paramId);
1648 return;
1649 }
1650 spin_unlock(&hdd_context_lock);
1651
Sunil Duttc69bccb2014-05-26 21:30:20 +05301652 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1653 {
1654 hdd_link_layer_process_radio_stats(pAdapter,
1655 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301656 spin_lock(&hdd_context_lock);
1657 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1658 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301659 }
1660 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1661 {
1662 hdd_link_layer_process_iface_stats(pAdapter,
1663 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301664 spin_lock(&hdd_context_lock);
1665 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1666 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301667 }
1668 else if ( linkLayerStatsResults->paramId &
1669 WMI_LINK_STATS_ALL_PEER )
1670 {
1671 hdd_link_layer_process_peer_stats(pAdapter,
1672 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301673 spin_lock(&hdd_context_lock);
1674 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1675 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301676 } /* WMI_LINK_STATS_ALL_PEER */
1677 else
1678 {
1679 hddLog(VOS_TRACE_LEVEL_ERROR,
1680 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1681 }
1682
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301683 spin_lock(&hdd_context_lock);
1684 /* complete response event if all requests are completed */
1685 if (0 == context->request_bitmap)
1686 complete(&context->response_event);
1687 spin_unlock(&hdd_context_lock);
1688
Sunil Duttc69bccb2014-05-26 21:30:20 +05301689 break;
1690 }
1691 default:
1692 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1693 break;
1694 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301695
1696 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301697 return;
1698}
1699
1700const struct
1701nla_policy
1702qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1703{
1704 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1705 { .type = NLA_U32 },
1706 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1707 { .type = NLA_U32 },
1708};
1709
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301710static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1711 struct wireless_dev *wdev,
1712 const void *data,
1713 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301714{
1715 int status;
1716 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301717 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301718 struct net_device *dev = wdev->netdev;
1719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1720 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1721
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301722 ENTER();
1723
Sunil Duttc69bccb2014-05-26 21:30:20 +05301724 status = wlan_hdd_validate_context(pHddCtx);
1725 if (0 != status)
1726 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301727 return -EINVAL;
1728 }
1729
1730 if (NULL == pAdapter)
1731 {
1732 hddLog(VOS_TRACE_LEVEL_ERROR,
1733 FL("HDD adapter is Null"));
1734 return -ENODEV;
1735 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301736 /* check the LLStats Capability */
1737 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1738 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1739 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05301740 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301741 FL("Link Layer Statistics not supported by Firmware"));
1742 return -EINVAL;
1743 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301744
1745 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1746 (struct nlattr *)data,
1747 data_len, qca_wlan_vendor_ll_set_policy))
1748 {
1749 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1750 return -EINVAL;
1751 }
1752 if (!tb_vendor
1753 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1754 {
1755 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1756 return -EINVAL;
1757 }
1758 if (!tb_vendor[
1759 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1760 {
1761 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1762 return -EINVAL;
1763 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301764 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301765 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301766
Dino Mycledf0a5d92014-07-04 09:41:55 +05301767 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301768 nla_get_u32(
1769 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1770
Dino Mycledf0a5d92014-07-04 09:41:55 +05301771 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301772 nla_get_u32(
1773 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1774
Dino Mycled3d50022014-07-07 12:58:25 +05301775 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1776 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301777
1778
1779 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301780 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1781 "Statistics Gathering = %d ",
1782 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1783 linkLayerStatsSetReq.mpduSizeThreshold,
1784 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301785
1786 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1787 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301788 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301789 {
1790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1791 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301792 return -EINVAL;
1793
1794 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301795
Sunil Duttc69bccb2014-05-26 21:30:20 +05301796 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301797 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301798 {
1799 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1800 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301801 return -EINVAL;
1802 }
1803
1804 pAdapter->isLinkLayerStatsSet = 1;
1805
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301806 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301807 return 0;
1808}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301809static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1810 struct wireless_dev *wdev,
1811 const void *data,
1812 int data_len)
1813{
1814 int ret = 0;
1815
1816 vos_ssr_protect(__func__);
1817 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1818 vos_ssr_unprotect(__func__);
1819
1820 return ret;
1821}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301822
1823const struct
1824nla_policy
1825qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1826{
1827 /* Unsigned 32bit value provided by the caller issuing the GET stats
1828 * command. When reporting
1829 * the stats results, the driver uses the same value to indicate
1830 * which GET request the results
1831 * correspond to.
1832 */
1833 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1834
1835 /* Unsigned 32bit value . bit mask to identify what statistics are
1836 requested for retrieval */
1837 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1838};
1839
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301840static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1841 struct wireless_dev *wdev,
1842 const void *data,
1843 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301844{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301845 unsigned long rc;
1846 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301847 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1848 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301849 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301850 struct net_device *dev = wdev->netdev;
1851 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301852 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301853 int status;
1854
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301855 ENTER();
1856
Sunil Duttc69bccb2014-05-26 21:30:20 +05301857 status = wlan_hdd_validate_context(pHddCtx);
1858 if (0 != status)
1859 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301860 return -EINVAL ;
1861 }
1862
1863 if (NULL == pAdapter)
1864 {
1865 hddLog(VOS_TRACE_LEVEL_FATAL,
1866 "%s: HDD adapter is Null", __func__);
1867 return -ENODEV;
1868 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301869
1870 if (pHddStaCtx == NULL)
1871 {
1872 hddLog(VOS_TRACE_LEVEL_FATAL,
1873 "%s: HddStaCtx is Null", __func__);
1874 return -ENODEV;
1875 }
1876
Dino Mycledf0a5d92014-07-04 09:41:55 +05301877 /* check the LLStats Capability */
1878 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1879 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1880 {
1881 hddLog(VOS_TRACE_LEVEL_ERROR,
1882 FL("Link Layer Statistics not supported by Firmware"));
1883 return -EINVAL;
1884 }
1885
Sunil Duttc69bccb2014-05-26 21:30:20 +05301886
1887 if (!pAdapter->isLinkLayerStatsSet)
1888 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05301889 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301890 "%s: isLinkLayerStatsSet : %d",
1891 __func__, pAdapter->isLinkLayerStatsSet);
1892 return -EINVAL;
1893 }
1894
Mukul Sharma10313ba2015-07-29 19:14:39 +05301895 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1896 {
1897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1898 "%s: Roaming in progress, so unable to proceed this request", __func__);
1899 return -EBUSY;
1900 }
1901
Sunil Duttc69bccb2014-05-26 21:30:20 +05301902 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1903 (struct nlattr *)data,
1904 data_len, qca_wlan_vendor_ll_get_policy))
1905 {
1906 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1907 return -EINVAL;
1908 }
1909
1910 if (!tb_vendor
1911 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1912 {
1913 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1914 return -EINVAL;
1915 }
1916
1917 if (!tb_vendor
1918 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1919 {
1920 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1921 return -EINVAL;
1922 }
1923
Sunil Duttc69bccb2014-05-26 21:30:20 +05301924
Dino Mycledf0a5d92014-07-04 09:41:55 +05301925 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301926 nla_get_u32( tb_vendor[
1927 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301928 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301929 nla_get_u32( tb_vendor[
1930 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1931
Dino Mycled3d50022014-07-07 12:58:25 +05301932 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1933 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301934
1935 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301936 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1937 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301938 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301939
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301940 spin_lock(&hdd_context_lock);
1941 context = &pHddCtx->ll_stats_context;
1942 context->request_id = linkLayerStatsGetReq.reqId;
1943 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1944 INIT_COMPLETION(context->response_event);
1945 spin_unlock(&hdd_context_lock);
1946
Sunil Duttc69bccb2014-05-26 21:30:20 +05301947 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301948 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301949 {
1950 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1951 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301952 return -EINVAL;
1953 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301954
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301955 rc = wait_for_completion_timeout(&context->response_event,
1956 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1957 if (!rc)
1958 {
1959 hddLog(LOGE,
1960 FL("Target response timed out request id %d request bitmap 0x%x"),
1961 context->request_id, context->request_bitmap);
1962 return -ETIMEDOUT;
1963 }
1964
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301965 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301966 return 0;
1967}
1968
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301969static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1970 struct wireless_dev *wdev,
1971 const void *data,
1972 int data_len)
1973{
1974 int ret = 0;
1975
1976 vos_ssr_protect(__func__);
1977 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1978 vos_ssr_unprotect(__func__);
1979
1980 return ret;
1981}
1982
Sunil Duttc69bccb2014-05-26 21:30:20 +05301983const struct
1984nla_policy
1985qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1986{
1987 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1988 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1989 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1990 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1991};
1992
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301993static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1994 struct wireless_dev *wdev,
1995 const void *data,
1996 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301997{
1998 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1999 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302000 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302001 struct net_device *dev = wdev->netdev;
2002 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2003 u32 statsClearReqMask;
2004 u8 stopReq;
2005 int status;
2006
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302007 ENTER();
2008
Sunil Duttc69bccb2014-05-26 21:30:20 +05302009 status = wlan_hdd_validate_context(pHddCtx);
2010 if (0 != status)
2011 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302012 return -EINVAL;
2013 }
2014
2015 if (NULL == pAdapter)
2016 {
2017 hddLog(VOS_TRACE_LEVEL_FATAL,
2018 "%s: HDD adapter is Null", __func__);
2019 return -ENODEV;
2020 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302021 /* check the LLStats Capability */
2022 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2023 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2024 {
2025 hddLog(VOS_TRACE_LEVEL_ERROR,
2026 FL("Enable LLStats Capability"));
2027 return -EINVAL;
2028 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302029
2030 if (!pAdapter->isLinkLayerStatsSet)
2031 {
2032 hddLog(VOS_TRACE_LEVEL_FATAL,
2033 "%s: isLinkLayerStatsSet : %d",
2034 __func__, pAdapter->isLinkLayerStatsSet);
2035 return -EINVAL;
2036 }
2037
2038 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2039 (struct nlattr *)data,
2040 data_len, qca_wlan_vendor_ll_clr_policy))
2041 {
2042 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2043 return -EINVAL;
2044 }
2045
2046 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2047
2048 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2049 {
2050 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2051 return -EINVAL;
2052
2053 }
2054
Sunil Duttc69bccb2014-05-26 21:30:20 +05302055
Dino Mycledf0a5d92014-07-04 09:41:55 +05302056 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302057 nla_get_u32(
2058 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2059
Dino Mycledf0a5d92014-07-04 09:41:55 +05302060 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302061 nla_get_u8(
2062 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2063
2064 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302065 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302066
Dino Mycled3d50022014-07-07 12:58:25 +05302067 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2068 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302069
2070 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302071 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2072 "statsClearReqMask = 0x%X, stopReq = %d",
2073 linkLayerStatsClearReq.reqId,
2074 linkLayerStatsClearReq.macAddr,
2075 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302076 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302077
2078 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302079 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302080 {
2081 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302082 hdd_station_ctx_t *pHddStaCtx;
2083
2084 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2085 if (VOS_STATUS_SUCCESS !=
2086 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2087 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2088 {
2089 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2090 "WLANTL_ClearInterfaceStats Failed", __func__);
2091 return -EINVAL;
2092 }
2093 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2094 (statsClearReqMask & WIFI_STATS_IFACE)) {
2095 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2096 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2097 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2098 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2099 }
2100
Sunil Duttc69bccb2014-05-26 21:30:20 +05302101 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2102 2 * sizeof(u32) +
2103 NLMSG_HDRLEN);
2104
2105 if (temp_skbuff != NULL)
2106 {
2107
2108 if (nla_put_u32(temp_skbuff,
2109 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2110 statsClearReqMask) ||
2111 nla_put_u32(temp_skbuff,
2112 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2113 stopReq))
2114 {
2115 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2116 kfree_skb(temp_skbuff);
2117 return -EINVAL;
2118 }
2119 /* If the ask is to stop the stats collection as part of clear
2120 * (stopReq = 1) , ensure that no further requests of get
2121 * go to the firmware by having isLinkLayerStatsSet set to 0.
2122 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302123 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302124 * case the firmware is just asked to clear the statistics.
2125 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302126 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302127 pAdapter->isLinkLayerStatsSet = 0;
2128 return cfg80211_vendor_cmd_reply(temp_skbuff);
2129 }
2130 return -ENOMEM;
2131 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302132
2133 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302134 return -EINVAL;
2135}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302136static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2137 struct wireless_dev *wdev,
2138 const void *data,
2139 int data_len)
2140{
2141 int ret = 0;
2142
2143 vos_ssr_protect(__func__);
2144 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2145 vos_ssr_unprotect(__func__);
2146
2147 return ret;
2148
2149
2150}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302151#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2152
Dino Mycle6fb96c12014-06-10 11:52:40 +05302153#ifdef WLAN_FEATURE_EXTSCAN
2154static const struct nla_policy
2155wlan_hdd_extscan_config_policy
2156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2157{
2158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2159 { .type = NLA_U32 },
2160 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2161 { .type = NLA_U32 },
2162 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2163 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2164 { .type = NLA_U32 },
2165 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2166 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2167
2168 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2169 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2170 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2171 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2172 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302173 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2174 { .type = NLA_U32 },
2175 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2176 { .type = NLA_U32 },
2177 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2178 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302179 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2180 { .type = NLA_U32 },
2181 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2182 { .type = NLA_U32 },
2183 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2184 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302185 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2186 { .type = NLA_U8 },
2187 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302188 { .type = NLA_U8 },
2189 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2190 { .type = NLA_U8 },
2191 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2192 { .type = NLA_U8 },
2193
2194 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2195 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05302196 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
2197 .type = NLA_UNSPEC,
2198 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05302199 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2200 { .type = NLA_S32 },
2201 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2202 { .type = NLA_S32 },
2203 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2204 { .type = NLA_U32 },
2205 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2206 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302207 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2208 { .type = NLA_U32 },
2209 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2210 { .type = NLA_BINARY,
2211 .len = IEEE80211_MAX_SSID_LEN + 1 },
2212 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302213 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302214 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2215 { .type = NLA_U32 },
2216 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2217 { .type = NLA_U8 },
2218 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2219 { .type = NLA_S32 },
2220 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2221 { .type = NLA_S32 },
2222 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2223 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302224};
2225
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302226/**
2227 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2228 * @ctx: hdd global context
2229 * @data: capabilities data
2230 *
2231 * Return: none
2232 */
2233static void
2234wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302235{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302236 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302237 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302238 tSirEXTScanCapabilitiesEvent *data =
2239 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302240
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302241 ENTER();
2242
2243 if (wlan_hdd_validate_context(pHddCtx))
2244 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302245 return;
2246 }
2247
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302248 if (!pMsg)
2249 {
2250 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2251 return;
2252 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302253
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302254 vos_spin_lock_acquire(&hdd_context_lock);
2255
2256 context = &pHddCtx->ext_scan_context;
2257 /* validate response received from target*/
2258 if (context->request_id != data->requestId)
2259 {
2260 vos_spin_lock_release(&hdd_context_lock);
2261 hddLog(LOGE,
2262 FL("Target response id did not match: request_id %d resposne_id %d"),
2263 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302264 return;
2265 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302266 else
2267 {
2268 context->capability_response = *data;
2269 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302270 }
2271
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302272 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302273
Dino Mycle6fb96c12014-06-10 11:52:40 +05302274 return;
2275}
2276
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302277/*
2278 * define short names for the global vendor params
2279 * used by wlan_hdd_send_ext_scan_capability()
2280 */
2281#define PARAM_REQUEST_ID \
2282 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2283#define PARAM_STATUS \
2284 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2285#define MAX_SCAN_CACHE_SIZE \
2286 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2287#define MAX_SCAN_BUCKETS \
2288 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2289#define MAX_AP_CACHE_PER_SCAN \
2290 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2291#define MAX_RSSI_SAMPLE_SIZE \
2292 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2293#define MAX_SCAN_RPT_THRHOLD \
2294 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2295#define MAX_HOTLIST_BSSIDS \
2296 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2297#define MAX_BSSID_HISTORY_ENTRIES \
2298 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2299#define MAX_HOTLIST_SSIDS \
2300 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302301#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2302 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302303
2304static int wlan_hdd_send_ext_scan_capability(void *ctx)
2305{
2306 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2307 struct sk_buff *skb = NULL;
2308 int ret;
2309 tSirEXTScanCapabilitiesEvent *data;
2310 tANI_U32 nl_buf_len;
2311
2312 ret = wlan_hdd_validate_context(pHddCtx);
2313 if (0 != ret)
2314 {
2315 return ret;
2316 }
2317
2318 data = &(pHddCtx->ext_scan_context.capability_response);
2319
2320 nl_buf_len = NLMSG_HDRLEN;
2321 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2322 (sizeof(data->status) + NLA_HDRLEN) +
2323 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2324 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2325 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2326 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2327 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2328 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2329 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2330 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2331
2332 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2333
2334 if (!skb)
2335 {
2336 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2337 return -ENOMEM;
2338 }
2339
2340 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2341 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2342 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2343 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2344 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2345 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2346 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2347 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2348
2349 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2350 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2351 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2352 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2353 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2354 data->maxApPerScan) ||
2355 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2356 data->maxRssiSampleSize) ||
2357 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2358 data->maxScanReportingThreshold) ||
2359 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2360 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2361 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302362 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2363 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302364 {
2365 hddLog(LOGE, FL("nla put fail"));
2366 goto nla_put_failure;
2367 }
2368
2369 cfg80211_vendor_cmd_reply(skb);
2370 return 0;
2371
2372nla_put_failure:
2373 kfree_skb(skb);
2374 return -EINVAL;;
2375}
2376
2377/*
2378 * done with short names for the global vendor params
2379 * used by wlan_hdd_send_ext_scan_capability()
2380 */
2381#undef PARAM_REQUEST_ID
2382#undef PARAM_STATUS
2383#undef MAX_SCAN_CACHE_SIZE
2384#undef MAX_SCAN_BUCKETS
2385#undef MAX_AP_CACHE_PER_SCAN
2386#undef MAX_RSSI_SAMPLE_SIZE
2387#undef MAX_SCAN_RPT_THRHOLD
2388#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302389#undef MAX_BSSID_HISTORY_ENTRIES
2390#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302391
2392static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2393{
2394 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2395 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302396 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302397 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302398
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302399 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302400
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302401 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302402 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302403
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302404 if (!pMsg)
2405 {
2406 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302407 return;
2408 }
2409
Dino Mycle6fb96c12014-06-10 11:52:40 +05302410 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2411 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2412
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302413 context = &pHddCtx->ext_scan_context;
2414 spin_lock(&hdd_context_lock);
2415 if (context->request_id == pData->requestId) {
2416 context->response_status = pData->status ? -EINVAL : 0;
2417 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302418 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302419 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302420
2421 /*
2422 * Store the Request ID for comparing with the requestID obtained
2423 * in other requests.HDD shall return a failure is the extscan_stop
2424 * request is issued with a different requestId as that of the
2425 * extscan_start request. Also, This requestId shall be used while
2426 * indicating the full scan results to the upper layers.
2427 * The requestId is stored with the assumption that the firmware
2428 * shall return the ext scan start request's requestId in ext scan
2429 * start response.
2430 */
2431 if (pData->status == 0)
2432 pMac->sme.extScanStartReqId = pData->requestId;
2433
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302434 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302435 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302436}
2437
2438
2439static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2440{
2441 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2442 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302443 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302444
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302445 ENTER();
2446
2447 if (wlan_hdd_validate_context(pHddCtx)){
2448 return;
2449 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302450
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302451 if (!pMsg)
2452 {
2453 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302454 return;
2455 }
2456
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302457 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2458 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302459
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302460 context = &pHddCtx->ext_scan_context;
2461 spin_lock(&hdd_context_lock);
2462 if (context->request_id == pData->requestId) {
2463 context->response_status = pData->status ? -EINVAL : 0;
2464 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302465 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302466 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302467
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302468 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302469 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302470}
2471
Dino Mycle6fb96c12014-06-10 11:52:40 +05302472static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2473 void *pMsg)
2474{
2475 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302476 tpSirEXTScanSetBssidHotListRspParams pData =
2477 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302478 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302479
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302480 ENTER();
2481
2482 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302483 return;
2484 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302485
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302486 if (!pMsg)
2487 {
2488 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2489 return;
2490 }
2491
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302492 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2493 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302494
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302495 context = &pHddCtx->ext_scan_context;
2496 spin_lock(&hdd_context_lock);
2497 if (context->request_id == pData->requestId) {
2498 context->response_status = pData->status ? -EINVAL : 0;
2499 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302500 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302501 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302502
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302503 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302504 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302505}
2506
2507static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2508 void *pMsg)
2509{
2510 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302511 tpSirEXTScanResetBssidHotlistRspParams pData =
2512 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302513 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302514
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302515 ENTER();
2516
2517 if (wlan_hdd_validate_context(pHddCtx)) {
2518 return;
2519 }
2520 if (!pMsg)
2521 {
2522 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302523 return;
2524 }
2525
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302526 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2527 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302528
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302529 context = &pHddCtx->ext_scan_context;
2530 spin_lock(&hdd_context_lock);
2531 if (context->request_id == pData->requestId) {
2532 context->response_status = pData->status ? -EINVAL : 0;
2533 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302534 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302535 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302536
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302537 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302538 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302539}
2540
Dino Mycle6fb96c12014-06-10 11:52:40 +05302541static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2542 void *pMsg)
2543{
2544 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2545 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302546 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302547 tANI_S32 totalResults;
2548 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302549 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2550 struct hdd_ext_scan_context *context;
2551 bool ignore_cached_results = false;
2552 tExtscanCachedScanResult *result;
2553 struct nlattr *nla_results;
2554 tANI_U16 ieLength= 0;
2555 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302556
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302557 ENTER();
2558
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302559 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302560 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302561
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302562 if (!pMsg)
2563 {
2564 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2565 return;
2566 }
2567
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302568 spin_lock(&hdd_context_lock);
2569 context = &pHddCtx->ext_scan_context;
2570 ignore_cached_results = context->ignore_cached_results;
2571 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302572
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302573 if (ignore_cached_results) {
2574 hddLog(LOGE,
2575 FL("Ignore the cached results received after timeout"));
2576 return;
2577 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302578
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302579 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2580 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302581
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302582 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302583
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302584 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2585 scan_id_index++) {
2586 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302587
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302588 totalResults = result->num_results;
2589 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2590 result->scan_id, result->flags, totalResults);
2591 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302592
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302593 do{
2594 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2595 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2596 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302597
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302598 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2599 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2600
2601 if (!skb) {
2602 hddLog(VOS_TRACE_LEVEL_ERROR,
2603 FL("cfg80211_vendor_event_alloc failed"));
2604 return;
2605 }
2606
2607 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2608
2609 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2610 pData->requestId) ||
2611 nla_put_u32(skb,
2612 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2613 resultsPerEvent)) {
2614 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2615 goto fail;
2616 }
2617 if (nla_put_u8(skb,
2618 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2619 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302620 {
2621 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2622 goto fail;
2623 }
2624
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302625 if (nla_put_u32(skb,
2626 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2627 result->scan_id)) {
2628 hddLog(LOGE, FL("put fail"));
2629 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302630 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302631
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302632 nla_results = nla_nest_start(skb,
2633 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2634 if (!nla_results)
2635 goto fail;
2636
2637 if (resultsPerEvent) {
2638 struct nlattr *aps;
2639 struct nlattr *nla_result;
2640
2641 nla_result = nla_nest_start(skb, scan_id_index);
2642 if(!nla_result)
2643 goto fail;
2644
2645 if (nla_put_u32(skb,
2646 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2647 result->scan_id) ||
2648 nla_put_u32(skb,
2649 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2650 result->flags) ||
2651 nla_put_u32(skb,
2652 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2653 totalResults)) {
2654 hddLog(LOGE, FL("put fail"));
2655 goto fail;
2656 }
2657
2658 aps = nla_nest_start(skb,
2659 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2660 if (!aps)
2661 {
2662 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2663 goto fail;
2664 }
2665
2666 head_ptr = (tpSirWifiScanResult) &(result->ap);
2667
2668 for (j = 0; j < resultsPerEvent; j++, i++) {
2669 struct nlattr *ap;
2670 pSirWifiScanResult = head_ptr + i;
2671
2672 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05302673 * Firmware returns timestamp from extscan_start till
2674 * BSSID was cached (in micro seconds). Add this with
2675 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302676 * to derive the time since boot when the
2677 * BSSID was cached.
2678 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05302679 pSirWifiScanResult->ts +=
2680 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302681 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2682 "Ssid (%s)"
2683 "Bssid: %pM "
2684 "Channel (%u)"
2685 "Rssi (%d)"
2686 "RTT (%u)"
2687 "RTT_SD (%u)"
2688 "Beacon Period %u"
2689 "Capability 0x%x "
2690 "Ie length %d",
2691 i,
2692 pSirWifiScanResult->ts,
2693 pSirWifiScanResult->ssid,
2694 pSirWifiScanResult->bssid,
2695 pSirWifiScanResult->channel,
2696 pSirWifiScanResult->rssi,
2697 pSirWifiScanResult->rtt,
2698 pSirWifiScanResult->rtt_sd,
2699 pSirWifiScanResult->beaconPeriod,
2700 pSirWifiScanResult->capability,
2701 ieLength);
2702
2703 ap = nla_nest_start(skb, j + 1);
2704 if (!ap)
2705 {
2706 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2707 goto fail;
2708 }
2709
2710 if (nla_put_u64(skb,
2711 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2712 pSirWifiScanResult->ts) )
2713 {
2714 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2715 goto fail;
2716 }
2717 if (nla_put(skb,
2718 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2719 sizeof(pSirWifiScanResult->ssid),
2720 pSirWifiScanResult->ssid) )
2721 {
2722 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2723 goto fail;
2724 }
2725 if (nla_put(skb,
2726 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2727 sizeof(pSirWifiScanResult->bssid),
2728 pSirWifiScanResult->bssid) )
2729 {
2730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2731 goto fail;
2732 }
2733 if (nla_put_u32(skb,
2734 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2735 pSirWifiScanResult->channel) )
2736 {
2737 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2738 goto fail;
2739 }
2740 if (nla_put_s32(skb,
2741 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2742 pSirWifiScanResult->rssi) )
2743 {
2744 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2745 goto fail;
2746 }
2747 if (nla_put_u32(skb,
2748 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2749 pSirWifiScanResult->rtt) )
2750 {
2751 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2752 goto fail;
2753 }
2754 if (nla_put_u32(skb,
2755 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2756 pSirWifiScanResult->rtt_sd))
2757 {
2758 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2759 goto fail;
2760 }
2761 if (nla_put_u32(skb,
2762 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2763 pSirWifiScanResult->beaconPeriod))
2764 {
2765 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2766 goto fail;
2767 }
2768 if (nla_put_u32(skb,
2769 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2770 pSirWifiScanResult->capability))
2771 {
2772 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2773 goto fail;
2774 }
2775 if (nla_put_u32(skb,
2776 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2777 ieLength))
2778 {
2779 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2780 goto fail;
2781 }
2782
2783 if (ieLength)
2784 if (nla_put(skb,
2785 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2786 ieLength, ie)) {
2787 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2788 goto fail;
2789 }
2790
2791 nla_nest_end(skb, ap);
2792 }
2793 nla_nest_end(skb, aps);
2794 nla_nest_end(skb, nla_result);
2795 }
2796
2797 nla_nest_end(skb, nla_results);
2798
2799 cfg80211_vendor_cmd_reply(skb);
2800
2801 } while (totalResults > 0);
2802 }
2803
2804 if (!pData->moreData) {
2805 spin_lock(&hdd_context_lock);
2806 context->response_status = 0;
2807 complete(&context->response_event);
2808 spin_unlock(&hdd_context_lock);
2809 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302810
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302811 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302812 return;
2813fail:
2814 kfree_skb(skb);
2815 return;
2816}
2817
2818static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2819 void *pMsg)
2820{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302821 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302822 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2823 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302824 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302825
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302826 ENTER();
2827
2828 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302829 hddLog(LOGE,
2830 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302831 return;
2832 }
2833 if (!pMsg)
2834 {
2835 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302836 return;
2837 }
2838
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302839 if (pData->bss_found)
2840 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2841 else
2842 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2843
Dino Mycle6fb96c12014-06-10 11:52:40 +05302844 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302845#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2846 NULL,
2847#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302848 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302849 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302850
2851 if (!skb) {
2852 hddLog(VOS_TRACE_LEVEL_ERROR,
2853 FL("cfg80211_vendor_event_alloc failed"));
2854 return;
2855 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302856
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302857 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2858 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2859 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2860 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2861
2862 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302863 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2864 "Ssid (%s) "
2865 "Bssid (" MAC_ADDRESS_STR ") "
2866 "Channel (%u) "
2867 "Rssi (%d) "
2868 "RTT (%u) "
2869 "RTT_SD (%u) ",
2870 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302871 pData->bssHotlist[i].ts,
2872 pData->bssHotlist[i].ssid,
2873 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2874 pData->bssHotlist[i].channel,
2875 pData->bssHotlist[i].rssi,
2876 pData->bssHotlist[i].rtt,
2877 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302878 }
2879
2880 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2881 pData->requestId) ||
2882 nla_put_u32(skb,
2883 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302884 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302885 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2886 goto fail;
2887 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302888 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302889 struct nlattr *aps;
2890
2891 aps = nla_nest_start(skb,
2892 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2893 if (!aps)
2894 goto fail;
2895
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302896 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302897 struct nlattr *ap;
2898
2899 ap = nla_nest_start(skb, i + 1);
2900 if (!ap)
2901 goto fail;
2902
2903 if (nla_put_u64(skb,
2904 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302905 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302906 nla_put(skb,
2907 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302908 sizeof(pData->bssHotlist[i].ssid),
2909 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302910 nla_put(skb,
2911 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302912 sizeof(pData->bssHotlist[i].bssid),
2913 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302914 nla_put_u32(skb,
2915 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302916 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302917 nla_put_s32(skb,
2918 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302919 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302920 nla_put_u32(skb,
2921 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302922 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302923 nla_put_u32(skb,
2924 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302925 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302926 goto fail;
2927
2928 nla_nest_end(skb, ap);
2929 }
2930 nla_nest_end(skb, aps);
2931
2932 if (nla_put_u8(skb,
2933 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2934 pData->moreData))
2935 goto fail;
2936 }
2937
2938 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302939 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302940 return;
2941
2942fail:
2943 kfree_skb(skb);
2944 return;
2945
2946}
Dino Mycle6fb96c12014-06-10 11:52:40 +05302947
2948static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2949 void *pMsg)
2950{
2951 struct sk_buff *skb;
2952 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2953 tpSirWifiFullScanResultEvent pData =
2954 (tpSirWifiFullScanResultEvent) (pMsg);
2955
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302956 ENTER();
2957
2958 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302959 hddLog(LOGE,
2960 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302961 return;
2962 }
2963 if (!pMsg)
2964 {
2965 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302966 return;
2967 }
2968
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302969 /*
2970 * If the full scan result including IE data exceeds NL 4K size
2971 * limitation, drop that beacon/probe rsp frame.
2972 */
2973 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
2974 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
2975 return;
2976 }
2977
Dino Mycle6fb96c12014-06-10 11:52:40 +05302978 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302979#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2980 NULL,
2981#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302982 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2983 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2984 GFP_KERNEL);
2985
2986 if (!skb) {
2987 hddLog(VOS_TRACE_LEVEL_ERROR,
2988 FL("cfg80211_vendor_event_alloc failed"));
2989 return;
2990 }
2991
Dino Mycle6fb96c12014-06-10 11:52:40 +05302992 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2993 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2994 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2995 "Ssid (%s)"
2996 "Bssid (" MAC_ADDRESS_STR ")"
2997 "Channel (%u)"
2998 "Rssi (%d)"
2999 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303000 "RTT_SD (%u)"
3001 "Bcn Period %d"
3002 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303003 pData->ap.ts,
3004 pData->ap.ssid,
3005 MAC_ADDR_ARRAY(pData->ap.bssid),
3006 pData->ap.channel,
3007 pData->ap.rssi,
3008 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303009 pData->ap.rtt_sd,
3010 pData->ap.beaconPeriod,
3011 pData->ap.capability);
3012
Dino Mycle6fb96c12014-06-10 11:52:40 +05303013 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3014 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3015 pData->requestId) ||
3016 nla_put_u64(skb,
3017 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3018 pData->ap.ts) ||
3019 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3020 sizeof(pData->ap.ssid),
3021 pData->ap.ssid) ||
3022 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3023 WNI_CFG_BSSID_LEN,
3024 pData->ap.bssid) ||
3025 nla_put_u32(skb,
3026 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3027 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303028 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303029 pData->ap.rssi) ||
3030 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3031 pData->ap.rtt) ||
3032 nla_put_u32(skb,
3033 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3034 pData->ap.rtt_sd) ||
3035 nla_put_u16(skb,
3036 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3037 pData->ap.beaconPeriod) ||
3038 nla_put_u16(skb,
3039 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3040 pData->ap.capability) ||
3041 nla_put_u32(skb,
3042 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303043 pData->ieLength) ||
3044 nla_put_u8(skb,
3045 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3046 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303047 {
3048 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3049 goto nla_put_failure;
3050 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303051
3052 if (pData->ieLength) {
3053 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3054 pData->ieLength,
3055 pData->ie))
3056 {
3057 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3058 goto nla_put_failure;
3059 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303060 }
3061
3062 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303063 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303064 return;
3065
3066nla_put_failure:
3067 kfree_skb(skb);
3068 return;
3069}
3070
3071static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3072 void *pMsg)
3073{
3074 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3075 struct sk_buff *skb = NULL;
3076 tpSirEXTScanResultsAvailableIndParams pData =
3077 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3078
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303079 ENTER();
3080
3081 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303082 hddLog(LOGE,
3083 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303084 return;
3085 }
3086 if (!pMsg)
3087 {
3088 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303089 return;
3090 }
3091
3092 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303093#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3094 NULL,
3095#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303096 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3097 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3098 GFP_KERNEL);
3099
3100 if (!skb) {
3101 hddLog(VOS_TRACE_LEVEL_ERROR,
3102 FL("cfg80211_vendor_event_alloc failed"));
3103 return;
3104 }
3105
Dino Mycle6fb96c12014-06-10 11:52:40 +05303106 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3107 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3108 pData->numResultsAvailable);
3109 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3110 pData->requestId) ||
3111 nla_put_u32(skb,
3112 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3113 pData->numResultsAvailable)) {
3114 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3115 goto nla_put_failure;
3116 }
3117
3118 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303119 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303120 return;
3121
3122nla_put_failure:
3123 kfree_skb(skb);
3124 return;
3125}
3126
3127static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3128{
3129 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3130 struct sk_buff *skb = NULL;
3131 tpSirEXTScanProgressIndParams pData =
3132 (tpSirEXTScanProgressIndParams) pMsg;
3133
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303134 ENTER();
3135
3136 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303137 hddLog(LOGE,
3138 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303139 return;
3140 }
3141 if (!pMsg)
3142 {
3143 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303144 return;
3145 }
3146
3147 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303148#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3149 NULL,
3150#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303151 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3152 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3153 GFP_KERNEL);
3154
3155 if (!skb) {
3156 hddLog(VOS_TRACE_LEVEL_ERROR,
3157 FL("cfg80211_vendor_event_alloc failed"));
3158 return;
3159 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303160 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303161 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3162 pData->extScanEventType);
3163 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3164 pData->status);
3165
3166 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3167 pData->extScanEventType) ||
3168 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303169 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3170 pData->requestId) ||
3171 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303172 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3173 pData->status)) {
3174 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3175 goto nla_put_failure;
3176 }
3177
3178 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303179 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303180 return;
3181
3182nla_put_failure:
3183 kfree_skb(skb);
3184 return;
3185}
3186
3187void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3188 void *pMsg)
3189{
3190 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3191
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303192 ENTER();
3193
Dino Mycle6fb96c12014-06-10 11:52:40 +05303194 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303195 return;
3196 }
3197
3198 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3199
3200
3201 switch(evType) {
3202 case SIR_HAL_EXTSCAN_START_RSP:
3203 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3204 break;
3205
3206 case SIR_HAL_EXTSCAN_STOP_RSP:
3207 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3208 break;
3209 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3210 /* There is no need to send this response to upper layer
3211 Just log the message */
3212 hddLog(VOS_TRACE_LEVEL_INFO,
3213 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3214 break;
3215 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3216 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3217 break;
3218
3219 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3220 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3221 break;
3222
Dino Mycle6fb96c12014-06-10 11:52:40 +05303223 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303224 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303225 break;
3226 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3227 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3228 break;
3229 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3230 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3231 break;
3232 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3233 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3234 break;
3235 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3236 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3237 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303238 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3239 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3240 break;
3241 default:
3242 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3243 break;
3244 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303245 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303246}
3247
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303248static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3249 struct wireless_dev *wdev,
3250 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303251{
Dino Myclee8843b32014-07-04 14:21:45 +05303252 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303253 struct net_device *dev = wdev->netdev;
3254 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3255 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3256 struct nlattr
3257 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3258 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303259 struct hdd_ext_scan_context *context;
3260 unsigned long rc;
3261 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303262
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303263 ENTER();
3264
Dino Mycle6fb96c12014-06-10 11:52:40 +05303265 status = wlan_hdd_validate_context(pHddCtx);
3266 if (0 != status)
3267 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303268 return -EINVAL;
3269 }
Dino Myclee8843b32014-07-04 14:21:45 +05303270 /* check the EXTScan Capability */
3271 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303272 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3273 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303274 {
3275 hddLog(VOS_TRACE_LEVEL_ERROR,
3276 FL("EXTScan not enabled/supported by Firmware"));
3277 return -EINVAL;
3278 }
3279
Dino Mycle6fb96c12014-06-10 11:52:40 +05303280 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3281 data, dataLen,
3282 wlan_hdd_extscan_config_policy)) {
3283 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3284 return -EINVAL;
3285 }
3286
3287 /* Parse and fetch request Id */
3288 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3289 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3290 return -EINVAL;
3291 }
3292
Dino Myclee8843b32014-07-04 14:21:45 +05303293 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303294 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303295 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303296
Dino Myclee8843b32014-07-04 14:21:45 +05303297 reqMsg.sessionId = pAdapter->sessionId;
3298 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303299
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303300 vos_spin_lock_acquire(&hdd_context_lock);
3301 context = &pHddCtx->ext_scan_context;
3302 context->request_id = reqMsg.requestId;
3303 INIT_COMPLETION(context->response_event);
3304 vos_spin_lock_release(&hdd_context_lock);
3305
Dino Myclee8843b32014-07-04 14:21:45 +05303306 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303307 if (!HAL_STATUS_SUCCESS(status)) {
3308 hddLog(VOS_TRACE_LEVEL_ERROR,
3309 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303310 return -EINVAL;
3311 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303312
3313 rc = wait_for_completion_timeout(&context->response_event,
3314 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3315 if (!rc) {
3316 hddLog(LOGE, FL("Target response timed out"));
3317 return -ETIMEDOUT;
3318 }
3319
3320 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3321 if (ret)
3322 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3323
3324 return ret;
3325
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303326 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303327 return 0;
3328}
3329
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303330static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3331 struct wireless_dev *wdev,
3332 const void *data, int dataLen)
3333{
3334 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303335
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303336 vos_ssr_protect(__func__);
3337 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3338 vos_ssr_unprotect(__func__);
3339
3340 return ret;
3341}
3342
3343static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3344 struct wireless_dev *wdev,
3345 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303346{
Dino Myclee8843b32014-07-04 14:21:45 +05303347 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303348 struct net_device *dev = wdev->netdev;
3349 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3350 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3351 struct nlattr
3352 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3353 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303354 struct hdd_ext_scan_context *context;
3355 unsigned long rc;
3356 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303357
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303358 ENTER();
3359
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303360 if (VOS_FTM_MODE == hdd_get_conparam()) {
3361 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3362 return -EINVAL;
3363 }
3364
Dino Mycle6fb96c12014-06-10 11:52:40 +05303365 status = wlan_hdd_validate_context(pHddCtx);
3366 if (0 != status)
3367 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303368 return -EINVAL;
3369 }
Dino Myclee8843b32014-07-04 14:21:45 +05303370 /* check the EXTScan Capability */
3371 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303372 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3373 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303374 {
3375 hddLog(VOS_TRACE_LEVEL_ERROR,
3376 FL("EXTScan not enabled/supported by Firmware"));
3377 return -EINVAL;
3378 }
3379
Dino Mycle6fb96c12014-06-10 11:52:40 +05303380 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3381 data, dataLen,
3382 wlan_hdd_extscan_config_policy)) {
3383 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3384 return -EINVAL;
3385 }
3386 /* Parse and fetch request Id */
3387 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3388 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3389 return -EINVAL;
3390 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303391
Dino Myclee8843b32014-07-04 14:21:45 +05303392 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303393 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3394
Dino Myclee8843b32014-07-04 14:21:45 +05303395 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303396
Dino Myclee8843b32014-07-04 14:21:45 +05303397 reqMsg.sessionId = pAdapter->sessionId;
3398 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303399
3400 /* Parse and fetch flush parameter */
3401 if (!tb
3402 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3403 {
3404 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3405 goto failed;
3406 }
Dino Myclee8843b32014-07-04 14:21:45 +05303407 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303408 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3409
Dino Myclee8843b32014-07-04 14:21:45 +05303410 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303411
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303412 spin_lock(&hdd_context_lock);
3413 context = &pHddCtx->ext_scan_context;
3414 context->request_id = reqMsg.requestId;
3415 context->ignore_cached_results = false;
3416 INIT_COMPLETION(context->response_event);
3417 spin_unlock(&hdd_context_lock);
3418
Dino Myclee8843b32014-07-04 14:21:45 +05303419 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303420 if (!HAL_STATUS_SUCCESS(status)) {
3421 hddLog(VOS_TRACE_LEVEL_ERROR,
3422 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303423 return -EINVAL;
3424 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303425
3426 rc = wait_for_completion_timeout(&context->response_event,
3427 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3428 if (!rc) {
3429 hddLog(LOGE, FL("Target response timed out"));
3430 retval = -ETIMEDOUT;
3431 spin_lock(&hdd_context_lock);
3432 context->ignore_cached_results = true;
3433 spin_unlock(&hdd_context_lock);
3434 } else {
3435 spin_lock(&hdd_context_lock);
3436 retval = context->response_status;
3437 spin_unlock(&hdd_context_lock);
3438 }
3439
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303440 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303441 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303442
3443failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303444 return -EINVAL;
3445}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303446static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3447 struct wireless_dev *wdev,
3448 const void *data, int dataLen)
3449{
3450 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303451
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303452 vos_ssr_protect(__func__);
3453 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3454 vos_ssr_unprotect(__func__);
3455
3456 return ret;
3457}
3458
3459static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303461 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303462{
3463 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3464 struct net_device *dev = wdev->netdev;
3465 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3466 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3467 struct nlattr
3468 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3469 struct nlattr
3470 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3471 struct nlattr *apTh;
3472 eHalStatus status;
3473 tANI_U8 i = 0;
3474 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303475 struct hdd_ext_scan_context *context;
3476 tANI_U32 request_id;
3477 unsigned long rc;
3478 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303479
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303480 ENTER();
3481
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303482 if (VOS_FTM_MODE == hdd_get_conparam()) {
3483 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3484 return -EINVAL;
3485 }
3486
Dino Mycle6fb96c12014-06-10 11:52:40 +05303487 status = wlan_hdd_validate_context(pHddCtx);
3488 if (0 != status)
3489 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303490 return -EINVAL;
3491 }
Dino Myclee8843b32014-07-04 14:21:45 +05303492 /* check the EXTScan Capability */
3493 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303494 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3495 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303496 {
3497 hddLog(VOS_TRACE_LEVEL_ERROR,
3498 FL("EXTScan not enabled/supported by Firmware"));
3499 return -EINVAL;
3500 }
3501
Dino Mycle6fb96c12014-06-10 11:52:40 +05303502 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3503 data, dataLen,
3504 wlan_hdd_extscan_config_policy)) {
3505 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3506 return -EINVAL;
3507 }
3508
3509 /* Parse and fetch request Id */
3510 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3511 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3512 return -EINVAL;
3513 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303514 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3515 vos_mem_malloc(sizeof(*pReqMsg));
3516 if (!pReqMsg) {
3517 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3518 return -ENOMEM;
3519 }
3520
Dino Myclee8843b32014-07-04 14:21:45 +05303521
Dino Mycle6fb96c12014-06-10 11:52:40 +05303522 pReqMsg->requestId = nla_get_u32(
3523 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3524 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3525
3526 /* Parse and fetch number of APs */
3527 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3528 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3529 goto fail;
3530 }
3531
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303532 /* Parse and fetch lost ap sample size */
3533 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3534 hddLog(LOGE, FL("attr lost ap sample size failed"));
3535 goto fail;
3536 }
3537
3538 pReqMsg->lostBssidSampleSize = nla_get_u32(
3539 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3540 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3541
Dino Mycle6fb96c12014-06-10 11:52:40 +05303542 pReqMsg->sessionId = pAdapter->sessionId;
3543 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3544
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303545 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303546 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05303547 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
3548 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
3549 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
3550 goto fail;
3551 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303552 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303553
3554 nla_for_each_nested(apTh,
3555 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05303556 if (i == pReqMsg->numBssid) {
3557 hddLog(LOGW, FL("Ignoring excess AP"));
3558 break;
3559 }
3560
Dino Mycle6fb96c12014-06-10 11:52:40 +05303561 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3562 nla_data(apTh), nla_len(apTh),
3563 NULL)) {
3564 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3565 goto fail;
3566 }
3567
3568 /* Parse and fetch MAC address */
3569 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3570 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3571 goto fail;
3572 }
3573 memcpy(pReqMsg->ap[i].bssid, nla_data(
3574 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3575 sizeof(tSirMacAddr));
3576 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3577
3578 /* Parse and fetch low RSSI */
3579 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3580 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3581 goto fail;
3582 }
3583 pReqMsg->ap[i].low = nla_get_s32(
3584 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3585 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3586
3587 /* Parse and fetch high RSSI */
3588 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3589 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3590 goto fail;
3591 }
3592 pReqMsg->ap[i].high = nla_get_s32(
3593 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3594 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3595 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303596 i++;
3597 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303598
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05303599 if (i < pReqMsg->numBssid) {
3600 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
3601 i, pReqMsg->numBssid);
3602 pReqMsg->numBssid = i;
3603 }
3604
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303605 context = &pHddCtx->ext_scan_context;
3606 spin_lock(&hdd_context_lock);
3607 INIT_COMPLETION(context->response_event);
3608 context->request_id = request_id = pReqMsg->requestId;
3609 spin_unlock(&hdd_context_lock);
3610
Dino Mycle6fb96c12014-06-10 11:52:40 +05303611 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3612 if (!HAL_STATUS_SUCCESS(status)) {
3613 hddLog(VOS_TRACE_LEVEL_ERROR,
3614 FL("sme_SetBssHotlist failed(err=%d)"), status);
3615 vos_mem_free(pReqMsg);
3616 return -EINVAL;
3617 }
3618
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303619 /* request was sent -- wait for the response */
3620 rc = wait_for_completion_timeout(&context->response_event,
3621 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3622
3623 if (!rc) {
3624 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3625 retval = -ETIMEDOUT;
3626 } else {
3627 spin_lock(&hdd_context_lock);
3628 if (context->request_id == request_id)
3629 retval = context->response_status;
3630 else
3631 retval = -EINVAL;
3632 spin_unlock(&hdd_context_lock);
3633 }
3634
Dino Myclee8843b32014-07-04 14:21:45 +05303635 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303636 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303637 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303638
3639fail:
3640 vos_mem_free(pReqMsg);
3641 return -EINVAL;
3642}
3643
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303644static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3645 struct wireless_dev *wdev,
3646 const void *data, int dataLen)
3647{
3648 int ret = 0;
3649
3650 vos_ssr_protect(__func__);
3651 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3652 dataLen);
3653 vos_ssr_unprotect(__func__);
3654
3655 return ret;
3656}
3657
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303658static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303659 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303660 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303661{
Agrawal Ashish16abf782016-08-18 22:42:59 +05303662 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3663 struct net_device *dev = wdev->netdev;
3664 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3665 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3666 uint8_t num_channels = 0;
3667 uint8_t num_chan_new = 0;
3668 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05303669 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05303670 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303671 tWifiBand wifiBand;
3672 eHalStatus status;
3673 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05303674 tANI_U8 i,j,k;
3675 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303676
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303677 ENTER();
3678
Dino Mycle6fb96c12014-06-10 11:52:40 +05303679 status = wlan_hdd_validate_context(pHddCtx);
3680 if (0 != status)
3681 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303682 return -EINVAL;
3683 }
Dino Myclee8843b32014-07-04 14:21:45 +05303684
Dino Mycle6fb96c12014-06-10 11:52:40 +05303685 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3686 data, dataLen,
3687 wlan_hdd_extscan_config_policy)) {
3688 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3689 return -EINVAL;
3690 }
3691
3692 /* Parse and fetch request Id */
3693 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3695 return -EINVAL;
3696 }
3697 requestId = nla_get_u32(
3698 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3699 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3700
3701 /* Parse and fetch wifi band */
3702 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3703 {
3704 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3705 return -EINVAL;
3706 }
3707 wifiBand = nla_get_u32(
3708 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3709 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3710
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05303711 /* Parse and fetch max channels */
3712 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
3713 {
3714 hddLog(LOGE, FL("attr max channels failed"));
3715 return -EINVAL;
3716 }
3717 maxChannels = nla_get_u32(
3718 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
3719 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
3720
Dino Mycle6fb96c12014-06-10 11:52:40 +05303721 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05303722 wifiBand, chan_list,
3723 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303724 if (eHAL_STATUS_SUCCESS != status) {
3725 hddLog(VOS_TRACE_LEVEL_ERROR,
3726 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3727 return -EINVAL;
3728 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05303729
Agrawal Ashish16abf782016-08-18 22:42:59 +05303730 num_channels = VOS_MIN(num_channels, maxChannels);
3731 num_chan_new = num_channels;
3732 /* remove the indoor only channels if iface is SAP */
3733 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
3734 {
3735 num_chan_new = 0;
3736 for (i = 0; i < num_channels; i++)
3737 for (j = 0; j < IEEE80211_NUM_BANDS; j++) {
3738 if (wiphy->bands[j] == NULL)
3739 continue;
3740 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
3741 if ((chan_list[i] ==
3742 wiphy->bands[j]->channels[k].center_freq) &&
3743 (!(wiphy->bands[j]->channels[k].flags &
3744 IEEE80211_CHAN_INDOOR_ONLY))) {
3745 chan_list[num_chan_new] = chan_list[i];
3746 num_chan_new++;
3747 }
3748 }
3749 }
3750 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05303751
Agrawal Ashish16abf782016-08-18 22:42:59 +05303752 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
3753 for (i = 0; i < num_chan_new; i++)
3754 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
3755 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303756
3757 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05303758 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05303759 NLMSG_HDRLEN);
3760
3761 if (!replySkb) {
3762 hddLog(VOS_TRACE_LEVEL_ERROR,
3763 FL("valid channels: buffer alloc fail"));
3764 return -EINVAL;
3765 }
3766 if (nla_put_u32(replySkb,
3767 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05303768 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303769 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05303770 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303771
3772 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3773 kfree_skb(replySkb);
3774 return -EINVAL;
3775 }
3776
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303777 ret = cfg80211_vendor_cmd_reply(replySkb);
3778
3779 EXIT();
3780 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303781}
3782
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303783static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3784 struct wireless_dev *wdev,
3785 const void *data, int dataLen)
3786{
3787 int ret = 0;
3788
3789 vos_ssr_protect(__func__);
3790 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
3791 dataLen);
3792 vos_ssr_unprotect(__func__);
3793
3794 return ret;
3795}
3796
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303797static int hdd_extscan_start_fill_bucket_channel_spec(
3798 hdd_context_t *pHddCtx,
3799 tpSirEXTScanStartReqParams pReqMsg,
3800 struct nlattr **tb)
3801{
3802 struct nlattr *bucket[
3803 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3804 struct nlattr *channel[
3805 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3806 struct nlattr *buckets;
3807 struct nlattr *channels;
3808 int rem1, rem2;
3809 eHalStatus status;
3810 tANI_U8 bktIndex, j, numChannels;
3811 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3812 tANI_U32 passive_max_chn_time, active_max_chn_time;
3813
3814 bktIndex = 0;
3815
3816 nla_for_each_nested(buckets,
3817 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3818 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05303819 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3820 nla_data(buckets), nla_len(buckets),
3821 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303822 hddLog(LOGE, FL("nla_parse failed"));
3823 return -EINVAL;
3824 }
3825
3826 /* Parse and fetch bucket spec */
3827 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3828 hddLog(LOGE, FL("attr bucket index failed"));
3829 return -EINVAL;
3830 }
3831 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
3832 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3833 hddLog(LOG1, FL("Bucket spec Index %d"),
3834 pReqMsg->buckets[bktIndex].bucket);
3835
3836 /* Parse and fetch wifi band */
3837 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3838 hddLog(LOGE, FL("attr wifi band failed"));
3839 return -EINVAL;
3840 }
3841 pReqMsg->buckets[bktIndex].band = nla_get_u8(
3842 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3843 hddLog(LOG1, FL("Wifi band %d"),
3844 pReqMsg->buckets[bktIndex].band);
3845
3846 /* Parse and fetch period */
3847 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3848 hddLog(LOGE, FL("attr period failed"));
3849 return -EINVAL;
3850 }
3851 pReqMsg->buckets[bktIndex].period = nla_get_u32(
3852 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3853 hddLog(LOG1, FL("period %d"),
3854 pReqMsg->buckets[bktIndex].period);
3855
3856 /* Parse and fetch report events */
3857 if (!bucket[
3858 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3859 hddLog(LOGE, FL("attr report events failed"));
3860 return -EINVAL;
3861 }
3862 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
3863 bucket[
3864 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3865 hddLog(LOG1, FL("report events %d"),
3866 pReqMsg->buckets[bktIndex].reportEvents);
3867
3868 /* Parse and fetch max period */
3869 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
3870 hddLog(LOGE, FL("attr max period failed"));
3871 return -EINVAL;
3872 }
3873 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
3874 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
3875 hddLog(LOG1, FL("max period %u"),
3876 pReqMsg->buckets[bktIndex].max_period);
3877
3878 /* Parse and fetch exponent */
3879 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
3880 hddLog(LOGE, FL("attr exponent failed"));
3881 return -EINVAL;
3882 }
3883 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
3884 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
3885 hddLog(LOG1, FL("exponent %u"),
3886 pReqMsg->buckets[bktIndex].exponent);
3887
3888 /* Parse and fetch step count */
3889 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
3890 hddLog(LOGE, FL("attr step count failed"));
3891 return -EINVAL;
3892 }
3893 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
3894 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
3895 hddLog(LOG1, FL("Step count %u"),
3896 pReqMsg->buckets[bktIndex].step_count);
3897
3898 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
3899 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
3900
3901 /* Framework shall pass the channel list if the input WiFi band is
3902 * WIFI_BAND_UNSPECIFIED.
3903 * If the input WiFi band is specified (any value other than
3904 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
3905 */
3906 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
3907 numChannels = 0;
3908 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
3909 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
3910 pReqMsg->buckets[bktIndex].band,
3911 chanList, &numChannels);
3912 if (!HAL_STATUS_SUCCESS(status)) {
3913 hddLog(LOGE,
3914 FL("sme_GetValidChannelsByBand failed (err=%d)"),
3915 status);
3916 return -EINVAL;
3917 }
3918
3919 pReqMsg->buckets[bktIndex].numChannels =
3920 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
3921 hddLog(LOG1, FL("Num channels %d"),
3922 pReqMsg->buckets[bktIndex].numChannels);
3923
3924 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
3925 j++) {
3926 pReqMsg->buckets[bktIndex].channels[j].channel =
3927 chanList[j];
3928 pReqMsg->buckets[bktIndex].channels[j].
3929 chnlClass = 0;
3930 if (CSR_IS_CHANNEL_DFS(
3931 vos_freq_to_chan(chanList[j]))) {
3932 pReqMsg->buckets[bktIndex].channels[j].
3933 passive = 1;
3934 pReqMsg->buckets[bktIndex].channels[j].
3935 dwellTimeMs = passive_max_chn_time;
3936 } else {
3937 pReqMsg->buckets[bktIndex].channels[j].
3938 passive = 0;
3939 pReqMsg->buckets[bktIndex].channels[j].
3940 dwellTimeMs = active_max_chn_time;
3941 }
3942
3943 hddLog(LOG1,
3944 "Channel %u Passive %u Dwell time %u ms",
3945 pReqMsg->buckets[bktIndex].channels[j].channel,
3946 pReqMsg->buckets[bktIndex].channels[j].passive,
3947 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
3948 }
3949
3950 bktIndex++;
3951 continue;
3952 }
3953
3954 /* Parse and fetch number of channels */
3955 if (!bucket[
3956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
3957 hddLog(LOGE, FL("attr num channels failed"));
3958 return -EINVAL;
3959 }
3960
3961 pReqMsg->buckets[bktIndex].numChannels =
3962 nla_get_u32(bucket[
3963 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3964 hddLog(LOG1, FL("num channels %d"),
3965 pReqMsg->buckets[bktIndex].numChannels);
3966
3967 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3968 hddLog(LOGE, FL("attr channel spec failed"));
3969 return -EINVAL;
3970 }
3971
3972 j = 0;
3973 nla_for_each_nested(channels,
3974 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3975 if (nla_parse(channel,
3976 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3977 nla_data(channels), nla_len(channels),
3978 wlan_hdd_extscan_config_policy)) {
3979 hddLog(LOGE, FL("nla_parse failed"));
3980 return -EINVAL;
3981 }
3982
3983 /* Parse and fetch channel */
3984 if (!channel[
3985 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3986 hddLog(LOGE, FL("attr channel failed"));
3987 return -EINVAL;
3988 }
3989 pReqMsg->buckets[bktIndex].channels[j].channel =
3990 nla_get_u32(channel[
3991 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3992 hddLog(LOG1, FL("channel %u"),
3993 pReqMsg->buckets[bktIndex].channels[j].channel);
3994
3995 /* Parse and fetch dwell time */
3996 if (!channel[
3997 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3998 hddLog(LOGE, FL("attr dwelltime failed"));
3999 return -EINVAL;
4000 }
4001 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4002 nla_get_u32(channel[
4003 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4004
4005 hddLog(LOG1, FL("Dwell time (%u ms)"),
4006 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4007
4008
4009 /* Parse and fetch channel spec passive */
4010 if (!channel[
4011 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4012 hddLog(LOGE,
4013 FL("attr channel spec passive failed"));
4014 return -EINVAL;
4015 }
4016 pReqMsg->buckets[bktIndex].channels[j].passive =
4017 nla_get_u8(channel[
4018 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4019 hddLog(LOG1, FL("Chnl spec passive %u"),
4020 pReqMsg->buckets[bktIndex].channels[j].passive);
4021
4022 j++;
4023 }
4024
4025 bktIndex++;
4026 }
4027
4028 return 0;
4029}
4030
4031
4032/*
4033 * define short names for the global vendor params
4034 * used by wlan_hdd_cfg80211_extscan_start()
4035 */
4036#define PARAM_MAX \
4037QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4038#define PARAM_REQUEST_ID \
4039QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4040#define PARAM_BASE_PERIOD \
4041QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4042#define PARAM_MAX_AP_PER_SCAN \
4043QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4044#define PARAM_RPT_THRHLD_PERCENT \
4045QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4046#define PARAM_RPT_THRHLD_NUM_SCANS \
4047QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4048#define PARAM_NUM_BUCKETS \
4049QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4050
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304051static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304052 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304053 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304054{
Dino Myclee8843b32014-07-04 14:21:45 +05304055 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304056 struct net_device *dev = wdev->netdev;
4057 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4058 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4059 struct nlattr *tb[PARAM_MAX + 1];
4060 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304061 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304062 tANI_U32 request_id;
4063 struct hdd_ext_scan_context *context;
4064 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304065
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304066 ENTER();
4067
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304068 if (VOS_FTM_MODE == hdd_get_conparam()) {
4069 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4070 return -EINVAL;
4071 }
4072
Dino Mycle6fb96c12014-06-10 11:52:40 +05304073 status = wlan_hdd_validate_context(pHddCtx);
4074 if (0 != status)
4075 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304076 return -EINVAL;
4077 }
Dino Myclee8843b32014-07-04 14:21:45 +05304078 /* check the EXTScan Capability */
4079 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304080 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4081 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304082 {
4083 hddLog(VOS_TRACE_LEVEL_ERROR,
4084 FL("EXTScan not enabled/supported by Firmware"));
4085 return -EINVAL;
4086 }
4087
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304088 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304089 data, dataLen,
4090 wlan_hdd_extscan_config_policy)) {
4091 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4092 return -EINVAL;
4093 }
4094
4095 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304096 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304097 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4098 return -EINVAL;
4099 }
4100
Dino Myclee8843b32014-07-04 14:21:45 +05304101 pReqMsg = (tpSirEXTScanStartReqParams)
4102 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304103 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304104 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4105 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304106 }
4107
4108 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304109 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304110 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4111
4112 pReqMsg->sessionId = pAdapter->sessionId;
4113 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4114
4115 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304116 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304117 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4118 goto fail;
4119 }
4120 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304121 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304122 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4123 pReqMsg->basePeriod);
4124
4125 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304126 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304127 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4128 goto fail;
4129 }
4130 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304131 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304132 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4133 pReqMsg->maxAPperScan);
4134
4135 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304136 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304137 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4138 goto fail;
4139 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304140 pReqMsg->reportThresholdPercent = nla_get_u8(
4141 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304142 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304143 pReqMsg->reportThresholdPercent);
4144
4145 /* Parse and fetch report threshold num scans */
4146 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4147 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4148 goto fail;
4149 }
4150 pReqMsg->reportThresholdNumScans = nla_get_u8(
4151 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4152 hddLog(LOG1, FL("Report Threshold num scans %d"),
4153 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304154
4155 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304156 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304157 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4158 goto fail;
4159 }
4160 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304161 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304162 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4163 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4164 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4165 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4166 }
4167 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4168 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304169
Dino Mycle6fb96c12014-06-10 11:52:40 +05304170 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4171 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4172 goto fail;
4173 }
4174
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304175 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304176
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304177 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4178 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304179
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304180 context = &pHddCtx->ext_scan_context;
4181 spin_lock(&hdd_context_lock);
4182 INIT_COMPLETION(context->response_event);
4183 context->request_id = request_id = pReqMsg->requestId;
4184 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304185
Dino Mycle6fb96c12014-06-10 11:52:40 +05304186 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4187 if (!HAL_STATUS_SUCCESS(status)) {
4188 hddLog(VOS_TRACE_LEVEL_ERROR,
4189 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304190 goto fail;
4191 }
4192
Srinivas Dasari91727c12016-03-23 17:59:06 +05304193 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
4194
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304195 /* request was sent -- wait for the response */
4196 rc = wait_for_completion_timeout(&context->response_event,
4197 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4198
4199 if (!rc) {
4200 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4201 retval = -ETIMEDOUT;
4202 } else {
4203 spin_lock(&hdd_context_lock);
4204 if (context->request_id == request_id)
4205 retval = context->response_status;
4206 else
4207 retval = -EINVAL;
4208 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304209 }
4210
Dino Myclee8843b32014-07-04 14:21:45 +05304211 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304212 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304213 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304214
4215fail:
4216 vos_mem_free(pReqMsg);
4217 return -EINVAL;
4218}
4219
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304220/*
4221 * done with short names for the global vendor params
4222 * used by wlan_hdd_cfg80211_extscan_start()
4223 */
4224#undef PARAM_MAX
4225#undef PARAM_REQUEST_ID
4226#undef PARAM_BASE_PERIOD
4227#undef PARAMS_MAX_AP_PER_SCAN
4228#undef PARAMS_RPT_THRHLD_PERCENT
4229#undef PARAMS_RPT_THRHLD_NUM_SCANS
4230#undef PARAMS_NUM_BUCKETS
4231
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304232static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4233 struct wireless_dev *wdev,
4234 const void *data, int dataLen)
4235{
4236 int ret = 0;
4237
4238 vos_ssr_protect(__func__);
4239 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4240 vos_ssr_unprotect(__func__);
4241
4242 return ret;
4243}
4244
4245static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304246 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304247 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304248{
Dino Myclee8843b32014-07-04 14:21:45 +05304249 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304250 struct net_device *dev = wdev->netdev;
4251 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4252 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4253 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4254 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304255 int retval;
4256 unsigned long rc;
4257 struct hdd_ext_scan_context *context;
4258 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304259
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304260 ENTER();
4261
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304262 if (VOS_FTM_MODE == hdd_get_conparam()) {
4263 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4264 return -EINVAL;
4265 }
4266
Dino Mycle6fb96c12014-06-10 11:52:40 +05304267 status = wlan_hdd_validate_context(pHddCtx);
4268 if (0 != status)
4269 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304270 return -EINVAL;
4271 }
Dino Myclee8843b32014-07-04 14:21:45 +05304272 /* check the EXTScan Capability */
4273 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304274 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4275 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304276 {
4277 hddLog(VOS_TRACE_LEVEL_ERROR,
4278 FL("EXTScan not enabled/supported by Firmware"));
4279 return -EINVAL;
4280 }
4281
Dino Mycle6fb96c12014-06-10 11:52:40 +05304282 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4283 data, dataLen,
4284 wlan_hdd_extscan_config_policy)) {
4285 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4286 return -EINVAL;
4287 }
4288
4289 /* Parse and fetch request Id */
4290 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4291 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4292 return -EINVAL;
4293 }
4294
Dino Myclee8843b32014-07-04 14:21:45 +05304295 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304296 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304297 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304298
Dino Myclee8843b32014-07-04 14:21:45 +05304299 reqMsg.sessionId = pAdapter->sessionId;
4300 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304301
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304302 context = &pHddCtx->ext_scan_context;
4303 spin_lock(&hdd_context_lock);
4304 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05304305 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304306 spin_unlock(&hdd_context_lock);
4307
Dino Myclee8843b32014-07-04 14:21:45 +05304308 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304309 if (!HAL_STATUS_SUCCESS(status)) {
4310 hddLog(VOS_TRACE_LEVEL_ERROR,
4311 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304312 return -EINVAL;
4313 }
4314
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304315 /* request was sent -- wait for the response */
4316 rc = wait_for_completion_timeout(&context->response_event,
4317 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4318
4319 if (!rc) {
4320 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4321 retval = -ETIMEDOUT;
4322 } else {
4323 spin_lock(&hdd_context_lock);
4324 if (context->request_id == request_id)
4325 retval = context->response_status;
4326 else
4327 retval = -EINVAL;
4328 spin_unlock(&hdd_context_lock);
4329 }
4330
4331 return retval;
4332
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304333 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304334 return 0;
4335}
4336
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304337static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4338 struct wireless_dev *wdev,
4339 const void *data, int dataLen)
4340{
4341 int ret = 0;
4342
4343 vos_ssr_protect(__func__);
4344 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4345 vos_ssr_unprotect(__func__);
4346
4347 return ret;
4348}
4349
4350static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304351 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304352 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304353{
Dino Myclee8843b32014-07-04 14:21:45 +05304354 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304355 struct net_device *dev = wdev->netdev;
4356 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4357 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4358 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4359 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304360 struct hdd_ext_scan_context *context;
4361 tANI_U32 request_id;
4362 unsigned long rc;
4363 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304364
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304365 ENTER();
4366
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304367 if (VOS_FTM_MODE == hdd_get_conparam()) {
4368 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4369 return -EINVAL;
4370 }
4371
Dino Mycle6fb96c12014-06-10 11:52:40 +05304372 status = wlan_hdd_validate_context(pHddCtx);
4373 if (0 != status)
4374 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304375 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304376 return -EINVAL;
4377 }
Dino Myclee8843b32014-07-04 14:21:45 +05304378 /* check the EXTScan Capability */
4379 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304380 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4381 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304382 {
4383 hddLog(VOS_TRACE_LEVEL_ERROR,
4384 FL("EXTScan not enabled/supported by Firmware"));
4385 return -EINVAL;
4386 }
4387
Dino Mycle6fb96c12014-06-10 11:52:40 +05304388 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4389 data, dataLen,
4390 wlan_hdd_extscan_config_policy)) {
4391 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4392 return -EINVAL;
4393 }
4394
4395 /* Parse and fetch request Id */
4396 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4397 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4398 return -EINVAL;
4399 }
4400
Dino Myclee8843b32014-07-04 14:21:45 +05304401 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304402 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304403 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304404
Dino Myclee8843b32014-07-04 14:21:45 +05304405 reqMsg.sessionId = pAdapter->sessionId;
4406 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304407
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304408 context = &pHddCtx->ext_scan_context;
4409 spin_lock(&hdd_context_lock);
4410 INIT_COMPLETION(context->response_event);
4411 context->request_id = request_id = reqMsg.requestId;
4412 spin_unlock(&hdd_context_lock);
4413
Dino Myclee8843b32014-07-04 14:21:45 +05304414 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304415 if (!HAL_STATUS_SUCCESS(status)) {
4416 hddLog(VOS_TRACE_LEVEL_ERROR,
4417 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304418 return -EINVAL;
4419 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304420
4421 /* request was sent -- wait for the response */
4422 rc = wait_for_completion_timeout(&context->response_event,
4423 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4424 if (!rc) {
4425 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4426 retval = -ETIMEDOUT;
4427 } else {
4428 spin_lock(&hdd_context_lock);
4429 if (context->request_id == request_id)
4430 retval = context->response_status;
4431 else
4432 retval = -EINVAL;
4433 spin_unlock(&hdd_context_lock);
4434 }
4435
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304436 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304437 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304438}
4439
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304440static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4441 struct wireless_dev *wdev,
4442 const void *data, int dataLen)
4443{
4444 int ret = 0;
4445
4446 vos_ssr_protect(__func__);
4447 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4448 vos_ssr_unprotect(__func__);
4449
4450 return ret;
4451}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304452#endif /* WLAN_FEATURE_EXTSCAN */
4453
Atul Mittal115287b2014-07-08 13:26:33 +05304454/*EXT TDLS*/
4455static const struct nla_policy
4456wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4457{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05304458 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
4459 .type = NLA_UNSPEC,
4460 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05304461 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4462 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4463 {.type = NLA_S32 },
4464 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4465 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4466
4467};
4468
4469static const struct nla_policy
4470wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4471{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05304472 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
4473 .type = NLA_UNSPEC,
4474 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05304475
4476};
4477
4478static const struct nla_policy
4479wlan_hdd_tdls_config_state_change_policy[
4480 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4481{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05304482 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
4483 .type = NLA_UNSPEC,
4484 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05304485 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4486 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304487 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4488 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4489 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304490
4491};
4492
4493static const struct nla_policy
4494wlan_hdd_tdls_config_get_status_policy[
4495 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4496{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05304497 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
4498 .type = NLA_UNSPEC,
4499 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05304500 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4501 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304502 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4503 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4504 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304505
4506};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304507
4508static const struct nla_policy
4509wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4510{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05304511 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
4512 .type = NLA_UNSPEC,
4513 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304514};
4515
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304516static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304517 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304518 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304519 int data_len)
4520{
4521
4522 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4523 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4524
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304525 ENTER();
4526
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304527 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304528 return -EINVAL;
4529 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05304530 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05304531 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304532 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304533 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304534 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05304535 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304536 return -ENOTSUPP;
4537 }
4538
4539 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4540 data, data_len, wlan_hdd_mac_config)) {
4541 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4542 return -EINVAL;
4543 }
4544
4545 /* Parse and fetch mac address */
4546 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4547 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4548 return -EINVAL;
4549 }
4550
4551 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4552 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4553 VOS_MAC_ADDR_LAST_3_BYTES);
4554
Siddharth Bhal76972212014-10-15 16:22:51 +05304555 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4556
4557 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304558 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4559 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304560 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4561 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4562 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4563 {
4564 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4565 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4566 VOS_MAC_ADDRESS_LEN);
4567 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304568 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304569
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05304570 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
4571 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304572
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304573 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304574 return 0;
4575}
4576
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304577static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4578 struct wireless_dev *wdev,
4579 const void *data,
4580 int data_len)
4581{
4582 int ret = 0;
4583
4584 vos_ssr_protect(__func__);
4585 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
4586 vos_ssr_unprotect(__func__);
4587
4588 return ret;
4589}
4590
4591static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304592 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304593 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304594 int data_len)
4595{
4596 u8 peer[6] = {0};
4597 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[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4601 eHalStatus ret;
4602 tANI_S32 state;
4603 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304604 tANI_S32 global_operating_class = 0;
4605 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304606 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304607 int retVal;
4608
4609 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304610
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304611 if (!pAdapter) {
4612 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4613 return -EINVAL;
4614 }
4615
Atul Mittal115287b2014-07-08 13:26:33 +05304616 ret = wlan_hdd_validate_context(pHddCtx);
4617 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304618 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304619 return -EINVAL;
4620 }
4621 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304622 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304623 return -ENOTSUPP;
4624 }
4625 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4626 data, data_len,
4627 wlan_hdd_tdls_config_get_status_policy)) {
4628 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4629 return -EINVAL;
4630 }
4631
4632 /* Parse and fetch mac address */
4633 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4634 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4635 return -EINVAL;
4636 }
4637
4638 memcpy(peer, nla_data(
4639 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4640 sizeof(peer));
4641 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4642
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05304643 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05304644
Atul Mittal115287b2014-07-08 13:26:33 +05304645 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304646 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304647 NLMSG_HDRLEN);
4648
4649 if (!skb) {
4650 hddLog(VOS_TRACE_LEVEL_ERROR,
4651 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4652 return -EINVAL;
4653 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304654 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 +05304655 reason,
4656 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304657 global_operating_class,
4658 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304659 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304660 if (nla_put_s32(skb,
4661 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4662 state) ||
4663 nla_put_s32(skb,
4664 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4665 reason) ||
4666 nla_put_s32(skb,
4667 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4668 global_operating_class) ||
4669 nla_put_s32(skb,
4670 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4671 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304672
4673 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4674 goto nla_put_failure;
4675 }
4676
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304677 retVal = cfg80211_vendor_cmd_reply(skb);
4678 EXIT();
4679 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05304680
4681nla_put_failure:
4682 kfree_skb(skb);
4683 return -EINVAL;
4684}
4685
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304686static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4687 struct wireless_dev *wdev,
4688 const void *data,
4689 int data_len)
4690{
4691 int ret = 0;
4692
4693 vos_ssr_protect(__func__);
4694 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
4695 vos_ssr_unprotect(__func__);
4696
4697 return ret;
4698}
4699
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05304700static int wlan_hdd_cfg80211_exttdls_callback(
4701#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
4702 const tANI_U8* mac,
4703#else
4704 tANI_U8* mac,
4705#endif
Atul Mittal115287b2014-07-08 13:26:33 +05304706 tANI_S32 state,
4707 tANI_S32 reason,
4708 void *ctx)
4709{
4710 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05304711 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304712 tANI_S32 global_operating_class = 0;
4713 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304714 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05304715
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304716 ENTER();
4717
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304718 if (!pAdapter) {
4719 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4720 return -EINVAL;
4721 }
4722
4723 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05304724 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304726 return -EINVAL;
4727 }
4728
4729 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304731 return -ENOTSUPP;
4732 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304733 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
4734#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4735 NULL,
4736#endif
Atul Mittal115287b2014-07-08 13:26:33 +05304737 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4738 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4739 GFP_KERNEL);
4740
4741 if (!skb) {
4742 hddLog(VOS_TRACE_LEVEL_ERROR,
4743 FL("cfg80211_vendor_event_alloc failed"));
4744 return -EINVAL;
4745 }
4746 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304747 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4748 reason,
4749 state,
4750 global_operating_class,
4751 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304752 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4753 MAC_ADDR_ARRAY(mac));
4754
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304755 if (nla_put(skb,
4756 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4757 VOS_MAC_ADDR_SIZE, mac) ||
4758 nla_put_s32(skb,
4759 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4760 state) ||
4761 nla_put_s32(skb,
4762 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4763 reason) ||
4764 nla_put_s32(skb,
4765 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4766 channel) ||
4767 nla_put_s32(skb,
4768 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4769 global_operating_class)
4770 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304771 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4772 goto nla_put_failure;
4773 }
4774
4775 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304776 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05304777 return (0);
4778
4779nla_put_failure:
4780 kfree_skb(skb);
4781 return -EINVAL;
4782}
4783
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304784static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304785 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304786 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304787 int data_len)
4788{
4789 u8 peer[6] = {0};
4790 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304791 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4792 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4793 eHalStatus status;
4794 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304795 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304796 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304797
4798 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304799
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304800 if (!dev) {
4801 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4802 return -EINVAL;
4803 }
4804
4805 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4806 if (!pAdapter) {
4807 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4808 return -EINVAL;
4809 }
4810
Atul Mittal115287b2014-07-08 13:26:33 +05304811 status = wlan_hdd_validate_context(pHddCtx);
4812 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304813 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304814 return -EINVAL;
4815 }
4816 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304818 return -ENOTSUPP;
4819 }
4820 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4821 data, data_len,
4822 wlan_hdd_tdls_config_enable_policy)) {
4823 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4824 return -EINVAL;
4825 }
4826
4827 /* Parse and fetch mac address */
4828 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4829 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4830 return -EINVAL;
4831 }
4832
4833 memcpy(peer, nla_data(
4834 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4835 sizeof(peer));
4836 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4837
4838 /* Parse and fetch channel */
4839 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4840 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4841 return -EINVAL;
4842 }
4843 pReqMsg.channel = nla_get_s32(
4844 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4845 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4846
4847 /* Parse and fetch global operating class */
4848 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4849 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4850 return -EINVAL;
4851 }
4852 pReqMsg.global_operating_class = nla_get_s32(
4853 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4854 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4855 pReqMsg.global_operating_class);
4856
4857 /* Parse and fetch latency ms */
4858 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4859 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4860 return -EINVAL;
4861 }
4862 pReqMsg.max_latency_ms = nla_get_s32(
4863 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4864 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4865 pReqMsg.max_latency_ms);
4866
4867 /* Parse and fetch required bandwidth kbps */
4868 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4869 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4870 return -EINVAL;
4871 }
4872
4873 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4874 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4875 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4876 pReqMsg.min_bandwidth_kbps);
4877
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304878 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05304879 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05304880 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304881 wlan_hdd_cfg80211_exttdls_callback);
4882
4883 EXIT();
4884 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304885}
4886
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304887static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4888 struct wireless_dev *wdev,
4889 const void *data,
4890 int data_len)
4891{
4892 int ret = 0;
4893
4894 vos_ssr_protect(__func__);
4895 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
4896 vos_ssr_unprotect(__func__);
4897
4898 return ret;
4899}
4900
4901static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304902 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304903 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304904 int data_len)
4905{
4906 u8 peer[6] = {0};
4907 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304908 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4909 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4910 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304911 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304912 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304913
4914 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304915
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304916 if (!dev) {
4917 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4918 return -EINVAL;
4919 }
4920
4921 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4922 if (!pAdapter) {
4923 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
4924 return -EINVAL;
4925 }
4926
Atul Mittal115287b2014-07-08 13:26:33 +05304927 status = wlan_hdd_validate_context(pHddCtx);
4928 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304930 return -EINVAL;
4931 }
4932 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304933 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304934 return -ENOTSUPP;
4935 }
4936 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4937 data, data_len,
4938 wlan_hdd_tdls_config_disable_policy)) {
4939 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4940 return -EINVAL;
4941 }
4942 /* Parse and fetch mac address */
4943 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4944 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4945 return -EINVAL;
4946 }
4947
4948 memcpy(peer, nla_data(
4949 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4950 sizeof(peer));
4951 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4952
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304953 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
4954
4955 EXIT();
4956 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304957}
4958
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304959static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4960 struct wireless_dev *wdev,
4961 const void *data,
4962 int data_len)
4963{
4964 int ret = 0;
4965
4966 vos_ssr_protect(__func__);
4967 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
4968 vos_ssr_unprotect(__func__);
4969
4970 return ret;
4971}
4972
Dasari Srinivas7875a302014-09-26 17:50:57 +05304973static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304974__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05304975 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304976 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05304977{
4978 struct net_device *dev = wdev->netdev;
4979 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4980 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4981 struct sk_buff *skb = NULL;
4982 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304983 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05304984
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304985 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304986
4987 ret = wlan_hdd_validate_context(pHddCtx);
4988 if (0 != ret)
4989 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304990 return ret;
4991 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05304992 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
4993 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
4994 fset |= WIFI_FEATURE_INFRA;
4995 }
4996
4997 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
4998 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
4999 fset |= WIFI_FEATURE_INFRA_5G;
5000 }
5001
5002#ifdef WLAN_FEATURE_P2P
5003 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5004 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5005 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5006 fset |= WIFI_FEATURE_P2P;
5007 }
5008#endif
5009
5010 /* Soft-AP is supported currently by default */
5011 fset |= WIFI_FEATURE_SOFT_AP;
5012
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305013 /* HOTSPOT is a supplicant feature, enable it by default */
5014 fset |= WIFI_FEATURE_HOTSPOT;
5015
Dasari Srinivas7875a302014-09-26 17:50:57 +05305016#ifdef WLAN_FEATURE_EXTSCAN
5017 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305018 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5019 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5020 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305021 fset |= WIFI_FEATURE_EXTSCAN;
5022 }
5023#endif
5024
Dasari Srinivas7875a302014-09-26 17:50:57 +05305025 if (sme_IsFeatureSupportedByFW(NAN)) {
5026 hddLog(LOG1, FL("NAN is supported by firmware"));
5027 fset |= WIFI_FEATURE_NAN;
5028 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305029
5030 /* D2D RTT is not supported currently by default */
5031 if (sme_IsFeatureSupportedByFW(RTT)) {
5032 hddLog(LOG1, FL("RTT is supported by firmware"));
5033 fset |= WIFI_FEATURE_D2AP_RTT;
5034 }
5035
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305036 if (sme_IsFeatureSupportedByFW(RTT3)) {
5037 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5038 fset |= WIFI_FEATURE_RTT3;
5039 }
5040
Dasari Srinivas7875a302014-09-26 17:50:57 +05305041#ifdef FEATURE_WLAN_BATCH_SCAN
5042 if (fset & WIFI_FEATURE_EXTSCAN) {
5043 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5044 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5045 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5046 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5047 fset |= WIFI_FEATURE_BATCH_SCAN;
5048 }
5049#endif
5050
5051#ifdef FEATURE_WLAN_SCAN_PNO
5052 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5053 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5054 hddLog(LOG1, FL("PNO is supported by firmware"));
5055 fset |= WIFI_FEATURE_PNO;
5056 }
5057#endif
5058
5059 /* STA+STA is supported currently by default */
5060 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5061
5062#ifdef FEATURE_WLAN_TDLS
5063 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5064 sme_IsFeatureSupportedByFW(TDLS)) {
5065 hddLog(LOG1, FL("TDLS is supported by firmware"));
5066 fset |= WIFI_FEATURE_TDLS;
5067 }
5068
5069 /* TDLS_OFFCHANNEL is not supported currently by default */
5070#endif
5071
5072#ifdef WLAN_AP_STA_CONCURRENCY
5073 /* AP+STA concurrency is supported currently by default */
5074 fset |= WIFI_FEATURE_AP_STA;
5075#endif
5076
Mukul Sharma5add0532015-08-17 15:57:47 +05305077#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5078 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5079 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5080#endif
5081
Dasari Srinivas7875a302014-09-26 17:50:57 +05305082 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5083 NLMSG_HDRLEN);
5084
5085 if (!skb) {
5086 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5087 return -EINVAL;
5088 }
5089 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5090
5091 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5092 hddLog(LOGE, FL("nla put fail"));
5093 goto nla_put_failure;
5094 }
5095
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305096 ret = cfg80211_vendor_cmd_reply(skb);
5097 EXIT();
5098 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305099
5100nla_put_failure:
5101 kfree_skb(skb);
5102 return -EINVAL;
5103}
5104
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305105static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305106wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5107 struct wireless_dev *wdev,
5108 const void *data, int data_len)
5109{
5110 int ret = 0;
5111
5112 vos_ssr_protect(__func__);
5113 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5114 vos_ssr_unprotect(__func__);
5115
5116 return ret;
5117}
5118
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305119
5120static const struct
5121nla_policy
5122qca_wlan_vendor_wifi_logger_get_ring_data_policy
5123[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5124 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5125 = {.type = NLA_U32 },
5126};
5127
5128static int
5129 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5130 struct wireless_dev *wdev,
5131 const void *data,
5132 int data_len)
5133{
5134 int ret;
5135 VOS_STATUS status;
5136 uint32_t ring_id;
5137 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5138 struct nlattr *tb
5139 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5140
5141 ENTER();
5142
5143 ret = wlan_hdd_validate_context(hdd_ctx);
5144 if (0 != ret) {
5145 return ret;
5146 }
5147
5148 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5149 data, data_len,
5150 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5151 hddLog(LOGE, FL("Invalid attribute"));
5152 return -EINVAL;
5153 }
5154
5155 /* Parse and fetch ring id */
5156 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5157 hddLog(LOGE, FL("attr ATTR failed"));
5158 return -EINVAL;
5159 }
5160
5161 ring_id = nla_get_u32(
5162 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5163
5164 hddLog(LOG1, FL("Bug report triggered by framework"));
5165
5166 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5167 WLAN_LOG_INDICATOR_FRAMEWORK,
5168 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305169 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305170 );
5171 if (VOS_STATUS_SUCCESS != status) {
5172 hddLog(LOGE, FL("Failed to trigger bug report"));
5173
5174 return -EINVAL;
5175 }
5176
5177 return 0;
5178
5179
5180}
5181
5182
5183static int
5184 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5185 struct wireless_dev *wdev,
5186 const void *data,
5187 int data_len)
5188{
5189 int ret = 0;
5190
5191 vos_ssr_protect(__func__);
5192 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5193 wdev, data, data_len);
5194 vos_ssr_unprotect(__func__);
5195
5196 return ret;
5197
5198}
5199
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305200#define MAX_CONCURRENT_MATRIX \
5201 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
5202#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
5203 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
5204static const struct nla_policy
5205wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
5206 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
5207};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305208
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305209static int
5210__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305211 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305212 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305213{
5214 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5215 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305216 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305217 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305218 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5219 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305220
5221 ENTER();
5222
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305223 ret = wlan_hdd_validate_context(pHddCtx);
5224 if (0 != ret)
5225 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305226 return ret;
5227 }
5228
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305229 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
5230 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305231 hddLog(LOGE, FL("Invalid ATTR"));
5232 return -EINVAL;
5233 }
5234
5235 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305236 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305237 hddLog(LOGE, FL("Attr max feature set size failed"));
5238 return -EINVAL;
5239 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305240 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305241 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5242
5243 /* Fill feature combination matrix */
5244 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305245 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5246 WIFI_FEATURE_P2P;
5247
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305248 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5249 WIFI_FEATURE_SOFT_AP;
5250
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305251 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5252 WIFI_FEATURE_SOFT_AP;
5253
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305254 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5255 WIFI_FEATURE_SOFT_AP |
5256 WIFI_FEATURE_P2P;
5257
5258 /* Add more feature combinations here */
5259
5260 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5261 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5262 hddLog(LOG1, "Feature set matrix");
5263 for (i = 0; i < feature_sets; i++)
5264 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5265
5266 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5267 sizeof(u32) * feature_sets +
5268 NLMSG_HDRLEN);
5269
5270 if (reply_skb) {
5271 if (nla_put_u32(reply_skb,
5272 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5273 feature_sets) ||
5274 nla_put(reply_skb,
5275 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5276 sizeof(u32) * feature_sets, feature_set_matrix)) {
5277 hddLog(LOGE, FL("nla put fail"));
5278 kfree_skb(reply_skb);
5279 return -EINVAL;
5280 }
5281
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305282 ret = cfg80211_vendor_cmd_reply(reply_skb);
5283 EXIT();
5284 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305285 }
5286 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5287 return -ENOMEM;
5288
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305289}
5290
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305291#undef MAX_CONCURRENT_MATRIX
5292#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
5293
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305294static int
5295wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5296 struct wireless_dev *wdev,
5297 const void *data, int data_len)
5298{
5299 int ret = 0;
5300
5301 vos_ssr_protect(__func__);
5302 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5303 data_len);
5304 vos_ssr_unprotect(__func__);
5305
5306 return ret;
5307}
5308
c_manjeecfd1efb2015-09-25 19:32:34 +05305309
5310static int
5311__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5312 struct wireless_dev *wdev,
5313 const void *data, int data_len)
5314{
5315 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5316 int ret;
5317 ENTER();
5318
5319 ret = wlan_hdd_validate_context(pHddCtx);
5320 if (0 != ret)
5321 {
5322 return ret;
5323 }
5324
5325 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5326 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5327 {
5328 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5329 return -EINVAL;
5330 }
5331 /*call common API for FW mem dump req*/
5332 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5333
Abhishek Singhc783fa72015-12-09 18:07:34 +05305334 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305335 {
5336 /*indicate to userspace the status of fw mem dump */
5337 wlan_indicate_mem_dump_complete(true);
5338 }
5339 else
5340 {
5341 /*else send failure to userspace */
5342 wlan_indicate_mem_dump_complete(false);
5343 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305344 EXIT();
5345 return ret;
5346}
5347
5348/**
5349 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5350 * @wiphy: pointer to wireless wiphy structure.
5351 * @wdev: pointer to wireless_dev structure.
5352 * @data: Pointer to the NL data.
5353 * @data_len:Length of @data
5354 *
5355 * This is called when wlan driver needs to get the firmware memory dump
5356 * via vendor specific command.
5357 *
5358 * Return: 0 on success, error number otherwise.
5359 */
5360
5361static int
5362wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5363 struct wireless_dev *wdev,
5364 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305365{
5366 int ret = 0;
5367 vos_ssr_protect(__func__);
5368 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5369 data_len);
5370 vos_ssr_unprotect(__func__);
5371 return ret;
5372}
c_manjeecfd1efb2015-09-25 19:32:34 +05305373
Sushant Kaushik8e644982015-09-23 12:18:54 +05305374static const struct
5375nla_policy
5376qca_wlan_vendor_wifi_logger_start_policy
5377[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5378 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5379 = {.type = NLA_U32 },
5380 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5381 = {.type = NLA_U32 },
5382 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5383 = {.type = NLA_U32 },
5384};
5385
5386/**
5387 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5388 * or disable the collection of packet statistics from the firmware
5389 * @wiphy: WIPHY structure pointer
5390 * @wdev: Wireless device structure pointer
5391 * @data: Pointer to the data received
5392 * @data_len: Length of the data received
5393 *
5394 * This function is used to enable or disable the collection of packet
5395 * statistics from the firmware
5396 *
5397 * Return: 0 on success and errno on failure
5398 */
5399static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5400 struct wireless_dev *wdev,
5401 const void *data,
5402 int data_len)
5403{
5404 eHalStatus status;
5405 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5406 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5407 tAniWifiStartLog start_log;
5408
5409 status = wlan_hdd_validate_context(hdd_ctx);
5410 if (0 != status) {
5411 return -EINVAL;
5412 }
5413
5414 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5415 data, data_len,
5416 qca_wlan_vendor_wifi_logger_start_policy)) {
5417 hddLog(LOGE, FL("Invalid attribute"));
5418 return -EINVAL;
5419 }
5420
5421 /* Parse and fetch ring id */
5422 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5423 hddLog(LOGE, FL("attr ATTR failed"));
5424 return -EINVAL;
5425 }
5426 start_log.ringId = nla_get_u32(
5427 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5428 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5429
5430 /* Parse and fetch verbose level */
5431 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5432 hddLog(LOGE, FL("attr verbose_level failed"));
5433 return -EINVAL;
5434 }
5435 start_log.verboseLevel = nla_get_u32(
5436 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5437 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5438
5439 /* Parse and fetch flag */
5440 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5441 hddLog(LOGE, FL("attr flag failed"));
5442 return -EINVAL;
5443 }
5444 start_log.flag = nla_get_u32(
5445 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5446 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5447
5448 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305449 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5450 !vos_isPktStatsEnabled()))
5451
Sushant Kaushik8e644982015-09-23 12:18:54 +05305452 {
5453 hddLog(LOGE, FL("per pkt stats not enabled"));
5454 return -EINVAL;
5455 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305456
Sushant Kaushik33200572015-08-05 16:46:20 +05305457 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305458 return 0;
5459}
5460
5461/**
5462 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5463 * or disable the collection of packet statistics from the firmware
5464 * @wiphy: WIPHY structure pointer
5465 * @wdev: Wireless device structure pointer
5466 * @data: Pointer to the data received
5467 * @data_len: Length of the data received
5468 *
5469 * This function is used to enable or disable the collection of packet
5470 * statistics from the firmware
5471 *
5472 * Return: 0 on success and errno on failure
5473 */
5474static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5475 struct wireless_dev *wdev,
5476 const void *data,
5477 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05305478{
5479 int ret = 0;
5480
5481 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305482
5483 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
5484 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05305485 vos_ssr_unprotect(__func__);
5486
5487 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05305488}
5489
5490
Agarwal Ashish738843c2014-09-25 12:27:56 +05305491static const struct nla_policy
5492wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5493 +1] =
5494{
5495 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5496};
5497
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305498static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305499 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305500 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305501 int data_len)
5502{
5503 struct net_device *dev = wdev->netdev;
5504 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5505 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5506 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5507 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5508 eHalStatus status;
5509 u32 dfsFlag = 0;
5510
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305511 ENTER();
5512
Agarwal Ashish738843c2014-09-25 12:27:56 +05305513 status = wlan_hdd_validate_context(pHddCtx);
5514 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305515 return -EINVAL;
5516 }
5517 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5518 data, data_len,
5519 wlan_hdd_set_no_dfs_flag_config_policy)) {
5520 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5521 return -EINVAL;
5522 }
5523
5524 /* Parse and fetch required bandwidth kbps */
5525 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5526 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5527 return -EINVAL;
5528 }
5529
5530 dfsFlag = nla_get_u32(
5531 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5532 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5533 dfsFlag);
5534
5535 pHddCtx->disable_dfs_flag = dfsFlag;
5536
5537 sme_disable_dfs_channel(hHal, dfsFlag);
5538 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305539
5540 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305541 return 0;
5542}
Atul Mittal115287b2014-07-08 13:26:33 +05305543
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305544static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5545 struct wireless_dev *wdev,
5546 const void *data,
5547 int data_len)
5548{
5549 int ret = 0;
5550
5551 vos_ssr_protect(__func__);
5552 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5553 vos_ssr_unprotect(__func__);
5554
5555 return ret;
5556
5557}
5558
Mukul Sharma2a271632014-10-13 14:59:01 +05305559const struct
5560nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5561{
5562 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305563 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
5564 .type = NLA_UNSPEC,
5565 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05305566};
5567
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305568static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305569 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305570{
5571
5572 u8 bssid[6] = {0};
5573 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5574 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5575 eHalStatus status = eHAL_STATUS_SUCCESS;
5576 v_U32_t isFwrRoamEnabled = FALSE;
5577 int ret;
5578
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305579 ENTER();
5580
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305581 ret = wlan_hdd_validate_context(pHddCtx);
5582 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305583 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305584 }
5585
5586 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5587 data, data_len,
5588 qca_wlan_vendor_attr);
5589 if (ret){
5590 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5591 return -EINVAL;
5592 }
5593
5594 /* Parse and fetch Enable flag */
5595 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5596 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5597 return -EINVAL;
5598 }
5599
5600 isFwrRoamEnabled = nla_get_u32(
5601 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5602
5603 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5604
5605 /* Parse and fetch bssid */
5606 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5607 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5608 return -EINVAL;
5609 }
5610
5611 memcpy(bssid, nla_data(
5612 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5613 sizeof(bssid));
5614 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5615
5616 //Update roaming
5617 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05305618 if (!HAL_STATUS_SUCCESS(status)) {
5619 hddLog(LOGE,
5620 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
5621 return -EINVAL;
5622 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305623 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05305624 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05305625}
5626
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305627static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5628 struct wireless_dev *wdev, const void *data, int data_len)
5629{
5630 int ret = 0;
5631
5632 vos_ssr_protect(__func__);
5633 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5634 vos_ssr_unprotect(__func__);
5635
5636 return ret;
5637}
5638
Sushant Kaushik847890c2015-09-28 16:05:17 +05305639static const struct
5640nla_policy
5641qca_wlan_vendor_get_wifi_info_policy[
5642 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
5643 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
5644 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
5645};
5646
5647
5648/**
5649 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
5650 * @wiphy: pointer to wireless wiphy structure.
5651 * @wdev: pointer to wireless_dev structure.
5652 * @data: Pointer to the data to be passed via vendor interface
5653 * @data_len:Length of the data to be passed
5654 *
5655 * This is called when wlan driver needs to send wifi driver related info
5656 * (driver/fw version) to the user space application upon request.
5657 *
5658 * Return: Return the Success or Failure code.
5659 */
5660static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
5661 struct wireless_dev *wdev,
5662 const void *data, int data_len)
5663{
5664 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5665 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
5666 tSirVersionString version;
5667 uint32 version_len;
5668 uint8 attr;
5669 int status;
5670 struct sk_buff *reply_skb = NULL;
5671
5672 if (VOS_FTM_MODE == hdd_get_conparam()) {
5673 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5674 return -EINVAL;
5675 }
5676
5677 status = wlan_hdd_validate_context(hdd_ctx);
5678 if (0 != status) {
5679 hddLog(LOGE, FL("HDD context is not valid"));
5680 return -EINVAL;
5681 }
5682
5683 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
5684 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
5685 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
5686 return -EINVAL;
5687 }
5688
5689 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
5690 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
5691 QWLAN_VERSIONSTR);
5692 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
5693 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
5694 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
5695 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
5696 hdd_ctx->fw_Version);
5697 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
5698 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
5699 } else {
5700 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
5701 return -EINVAL;
5702 }
5703
5704 version_len = strlen(version);
5705 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
5706 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
5707 if (!reply_skb) {
5708 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5709 return -ENOMEM;
5710 }
5711
5712 if (nla_put(reply_skb, attr, version_len, version)) {
5713 hddLog(LOGE, FL("nla put fail"));
5714 kfree_skb(reply_skb);
5715 return -EINVAL;
5716 }
5717
5718 return cfg80211_vendor_cmd_reply(reply_skb);
5719}
5720
5721/**
5722 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
5723 * @wiphy: pointer to wireless wiphy structure.
5724 * @wdev: pointer to wireless_dev structure.
5725 * @data: Pointer to the data to be passed via vendor interface
5726 * @data_len:Length of the data to be passed
5727 * @data_len: Length of the data received
5728 *
5729 * This function is used to enable or disable the collection of packet
5730 * statistics from the firmware
5731 *
5732 * Return: 0 on success and errno on failure
5733 */
5734
5735static int
5736wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
5737 struct wireless_dev *wdev,
5738 const void *data, int data_len)
5739
5740
5741{
5742 int ret = 0;
5743
5744 vos_ssr_protect(__func__);
5745 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
5746 wdev, data, data_len);
5747 vos_ssr_unprotect(__func__);
5748
5749 return ret;
5750}
5751
5752
Gupta, Kapil7c34b322015-09-30 13:12:35 +05305753/*
5754 * define short names for the global vendor params
5755 * used by __wlan_hdd_cfg80211_monitor_rssi()
5756 */
5757#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
5758#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
5759#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
5760#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
5761#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
5762
5763/**---------------------------------------------------------------------------
5764
5765 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
5766 monitor start is completed successfully.
5767
5768 \return - None
5769
5770 --------------------------------------------------------------------------*/
5771void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
5772{
5773 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
5774
5775 if (NULL == pHddCtx)
5776 {
5777 hddLog(VOS_TRACE_LEVEL_ERROR,
5778 "%s: HDD context is NULL",__func__);
5779 return;
5780 }
5781
5782 if (VOS_STATUS_SUCCESS == status)
5783 {
5784 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
5785 }
5786 else
5787 {
5788 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
5789 }
5790
5791 return;
5792}
5793
5794/**---------------------------------------------------------------------------
5795
5796 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
5797 stop is completed successfully.
5798
5799 \return - None
5800
5801 --------------------------------------------------------------------------*/
5802void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
5803{
5804 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
5805
5806 if (NULL == pHddCtx)
5807 {
5808 hddLog(VOS_TRACE_LEVEL_ERROR,
5809 "%s: HDD context is NULL",__func__);
5810 return;
5811 }
5812
5813 if (VOS_STATUS_SUCCESS == status)
5814 {
5815 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
5816 }
5817 else
5818 {
5819 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
5820 }
5821
5822 return;
5823}
5824
5825/**
5826 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
5827 * @wiphy: Pointer to wireless phy
5828 * @wdev: Pointer to wireless device
5829 * @data: Pointer to data
5830 * @data_len: Data length
5831 *
5832 * Return: 0 on success, negative errno on failure
5833 */
5834
5835static int
5836__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
5837 struct wireless_dev *wdev,
5838 const void *data,
5839 int data_len)
5840{
5841 struct net_device *dev = wdev->netdev;
5842 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5843 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5844 hdd_station_ctx_t *pHddStaCtx;
5845 struct nlattr *tb[PARAM_MAX + 1];
5846 tpSirRssiMonitorReq pReq;
5847 eHalStatus status;
5848 int ret;
5849 uint32_t control;
5850 static const struct nla_policy policy[PARAM_MAX + 1] = {
5851 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
5852 [PARAM_CONTROL] = { .type = NLA_U32 },
5853 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
5854 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
5855 };
5856
5857 ENTER();
5858
5859 ret = wlan_hdd_validate_context(hdd_ctx);
5860 if (0 != ret) {
5861 return -EINVAL;
5862 }
5863
5864 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
5865 hddLog(LOGE, FL("Not in Connected state!"));
5866 return -ENOTSUPP;
5867 }
5868
5869 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
5870 hddLog(LOGE, FL("Invalid ATTR"));
5871 return -EINVAL;
5872 }
5873
5874 if (!tb[PARAM_REQUEST_ID]) {
5875 hddLog(LOGE, FL("attr request id failed"));
5876 return -EINVAL;
5877 }
5878
5879 if (!tb[PARAM_CONTROL]) {
5880 hddLog(LOGE, FL("attr control failed"));
5881 return -EINVAL;
5882 }
5883
5884 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5885
5886 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
5887 if(NULL == pReq)
5888 {
5889 hddLog(LOGE,
5890 FL("vos_mem_alloc failed "));
5891 return eHAL_STATUS_FAILED_ALLOC;
5892 }
5893 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
5894
5895 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
5896 pReq->sessionId = pAdapter->sessionId;
5897 pReq->rssiMonitorCbContext = hdd_ctx;
5898 control = nla_get_u32(tb[PARAM_CONTROL]);
5899 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
5900
5901 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
5902 pReq->requestId, pReq->sessionId, control);
5903
5904 if (control == QCA_WLAN_RSSI_MONITORING_START) {
5905 if (!tb[PARAM_MIN_RSSI]) {
5906 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05305907 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05305908 }
5909
5910 if (!tb[PARAM_MAX_RSSI]) {
5911 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05305912 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05305913 }
5914
5915 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
5916 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
5917 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
5918
5919 if (!(pReq->minRssi < pReq->maxRssi)) {
5920 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
5921 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05305922 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05305923 }
5924 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
5925 pReq->minRssi, pReq->maxRssi);
5926 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
5927
5928 }
5929 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
5930 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
5931 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
5932 }
5933 else {
5934 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05305935 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05305936 }
5937
5938 if (!HAL_STATUS_SUCCESS(status)) {
5939 hddLog(LOGE,
5940 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05305941 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05305942 }
5943
5944 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05305945fail:
5946 vos_mem_free(pReq);
5947 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05305948}
5949
5950/*
5951 * done with short names for the global vendor params
5952 * used by __wlan_hdd_cfg80211_monitor_rssi()
5953 */
5954#undef PARAM_MAX
5955#undef PARAM_CONTROL
5956#undef PARAM_REQUEST_ID
5957#undef PARAM_MAX_RSSI
5958#undef PARAM_MIN_RSSI
5959
5960/**
5961 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
5962 * @wiphy: wiphy structure pointer
5963 * @wdev: Wireless device structure pointer
5964 * @data: Pointer to the data received
5965 * @data_len: Length of @data
5966 *
5967 * Return: 0 on success; errno on failure
5968 */
5969static int
5970wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
5971 const void *data, int data_len)
5972{
5973 int ret;
5974
5975 vos_ssr_protect(__func__);
5976 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
5977 vos_ssr_unprotect(__func__);
5978
5979 return ret;
5980}
5981
5982/**
5983 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
5984 * @hddctx: HDD context
5985 * @data: rssi breached event data
5986 *
5987 * This function reads the rssi breached event %data and fill in the skb with
5988 * NL attributes and send up the NL event.
5989 * This callback execute in atomic context and must not invoke any
5990 * blocking calls.
5991 *
5992 * Return: none
5993 */
5994void hdd_rssi_threshold_breached_cb(void *hddctx,
5995 struct rssi_breach_event *data)
5996{
5997 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
5998 int status;
5999 struct sk_buff *skb;
6000
6001 ENTER();
6002 status = wlan_hdd_validate_context(pHddCtx);
6003
6004 if (0 != status) {
6005 return;
6006 }
6007
6008 if (!data) {
6009 hddLog(LOGE, FL("data is null"));
6010 return;
6011 }
6012
6013 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6014#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6015 NULL,
6016#endif
6017 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6018 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6019 GFP_KERNEL);
6020
6021 if (!skb) {
6022 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6023 return;
6024 }
6025
6026 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6027 data->request_id, data->curr_rssi);
6028 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6029 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6030
6031 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6032 data->request_id) ||
6033 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6034 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6035 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6036 data->curr_rssi)) {
6037 hddLog(LOGE, FL("nla put fail"));
6038 goto fail;
6039 }
6040
6041 cfg80211_vendor_event(skb, GFP_KERNEL);
6042 return;
6043
6044fail:
6045 kfree_skb(skb);
6046 return;
6047}
6048
6049
6050
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306051/**
6052 * __wlan_hdd_cfg80211_setband() - set band
6053 * @wiphy: Pointer to wireless phy
6054 * @wdev: Pointer to wireless device
6055 * @data: Pointer to data
6056 * @data_len: Data length
6057 *
6058 * Return: 0 on success, negative errno on failure
6059 */
6060static int
6061__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6062 struct wireless_dev *wdev,
6063 const void *data,
6064 int data_len)
6065{
6066 struct net_device *dev = wdev->netdev;
6067 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6068 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6069 int ret;
6070 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6071 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6072
6073 ENTER();
6074
6075 ret = wlan_hdd_validate_context(hdd_ctx);
6076 if (0 != ret) {
6077 hddLog(LOGE, FL("HDD context is not valid"));
6078 return ret;
6079 }
6080
6081 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6082 policy)) {
6083 hddLog(LOGE, FL("Invalid ATTR"));
6084 return -EINVAL;
6085 }
6086
6087 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6088 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6089 return -EINVAL;
6090 }
6091
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306092 hdd_ctx->isSetBandByNL = TRUE;
6093 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306094 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306095 hdd_ctx->isSetBandByNL = FALSE;
6096
6097 EXIT();
6098 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306099}
6100
6101/**
6102 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6103 * @wiphy: wiphy structure pointer
6104 * @wdev: Wireless device structure pointer
6105 * @data: Pointer to the data received
6106 * @data_len: Length of @data
6107 *
6108 * Return: 0 on success; errno on failure
6109 */
6110static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6111 struct wireless_dev *wdev,
6112 const void *data,
6113 int data_len)
6114{
6115 int ret = 0;
6116
6117 vos_ssr_protect(__func__);
6118 ret = __wlan_hdd_cfg80211_setband(wiphy,
6119 wdev, data, data_len);
6120 vos_ssr_unprotect(__func__);
6121
6122 return ret;
6123}
6124
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306125#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6126/**
6127 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6128 * @hdd_ctx: HDD context
6129 * @request_id: [input] request id
6130 * @pattern_id: [output] pattern id
6131 *
6132 * This function loops through request id to pattern id array
6133 * if the slot is available, store the request id and return pattern id
6134 * if entry exists, return the pattern id
6135 *
6136 * Return: 0 on success and errno on failure
6137 */
6138static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6139 uint32_t request_id,
6140 uint8_t *pattern_id)
6141{
6142 uint32_t i;
6143
6144 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6145 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6146 {
6147 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6148 {
6149 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6150 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6151 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6152 return 0;
6153 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6154 request_id) {
6155 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6156 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6157 return 0;
6158 }
6159 }
6160 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6161 return -EINVAL;
6162}
6163
6164/**
6165 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6166 * @hdd_ctx: HDD context
6167 * @request_id: [input] request id
6168 * @pattern_id: [output] pattern id
6169 *
6170 * This function loops through request id to pattern id array
6171 * reset request id to 0 (slot available again) and
6172 * return pattern id
6173 *
6174 * Return: 0 on success and errno on failure
6175 */
6176static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6177 uint32_t request_id,
6178 uint8_t *pattern_id)
6179{
6180 uint32_t i;
6181
6182 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6183 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6184 {
6185 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6186 {
6187 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6188 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6189 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6190 return 0;
6191 }
6192 }
6193 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6194 return -EINVAL;
6195}
6196
6197
6198/*
6199 * define short names for the global vendor params
6200 * used by __wlan_hdd_cfg80211_offloaded_packets()
6201 */
6202#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6203#define PARAM_REQUEST_ID \
6204 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6205#define PARAM_CONTROL \
6206 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6207#define PARAM_IP_PACKET \
6208 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6209#define PARAM_SRC_MAC_ADDR \
6210 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6211#define PARAM_DST_MAC_ADDR \
6212 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6213#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6214
6215/**
6216 * wlan_hdd_add_tx_ptrn() - add tx pattern
6217 * @adapter: adapter pointer
6218 * @hdd_ctx: hdd context
6219 * @tb: nl attributes
6220 *
6221 * This function reads the NL attributes and forms a AddTxPtrn message
6222 * posts it to SME.
6223 *
6224 */
6225static int
6226wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6227 struct nlattr **tb)
6228{
6229 struct sSirAddPeriodicTxPtrn *add_req;
6230 eHalStatus status;
6231 uint32_t request_id, ret, len;
6232 uint8_t pattern_id = 0;
6233 v_MACADDR_t dst_addr;
6234 uint16_t eth_type = htons(ETH_P_IP);
6235
6236 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6237 {
6238 hddLog(LOGE, FL("Not in Connected state!"));
6239 return -ENOTSUPP;
6240 }
6241
6242 add_req = vos_mem_malloc(sizeof(*add_req));
6243 if (!add_req)
6244 {
6245 hddLog(LOGE, FL("memory allocation failed"));
6246 return -ENOMEM;
6247 }
6248
6249 /* Parse and fetch request Id */
6250 if (!tb[PARAM_REQUEST_ID])
6251 {
6252 hddLog(LOGE, FL("attr request id failed"));
6253 goto fail;
6254 }
6255
6256 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6257 hddLog(LOG1, FL("Request Id: %u"), request_id);
6258 if (request_id == 0)
6259 {
6260 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306261 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306262 }
6263
6264 if (!tb[PARAM_PERIOD])
6265 {
6266 hddLog(LOGE, FL("attr period failed"));
6267 goto fail;
6268 }
6269 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6270 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6271 if (add_req->usPtrnIntervalMs == 0)
6272 {
6273 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6274 goto fail;
6275 }
6276
6277 if (!tb[PARAM_SRC_MAC_ADDR])
6278 {
6279 hddLog(LOGE, FL("attr source mac address failed"));
6280 goto fail;
6281 }
6282 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6283 VOS_MAC_ADDR_SIZE);
6284 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6285 MAC_ADDR_ARRAY(add_req->macAddress));
6286
6287 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6288 VOS_MAC_ADDR_SIZE))
6289 {
6290 hddLog(LOGE,
6291 FL("input src mac address and connected ap bssid are different"));
6292 goto fail;
6293 }
6294
6295 if (!tb[PARAM_DST_MAC_ADDR])
6296 {
6297 hddLog(LOGE, FL("attr dst mac address failed"));
6298 goto fail;
6299 }
6300 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6301 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6302 MAC_ADDR_ARRAY(dst_addr.bytes));
6303
6304 if (!tb[PARAM_IP_PACKET])
6305 {
6306 hddLog(LOGE, FL("attr ip packet failed"));
6307 goto fail;
6308 }
6309 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6310 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6311
6312 if (add_req->ucPtrnSize < 0 ||
6313 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6314 HDD_ETH_HEADER_LEN))
6315 {
6316 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6317 add_req->ucPtrnSize);
6318 goto fail;
6319 }
6320
6321 len = 0;
6322 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6323 len += VOS_MAC_ADDR_SIZE;
6324 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6325 VOS_MAC_ADDR_SIZE);
6326 len += VOS_MAC_ADDR_SIZE;
6327 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6328 len += 2;
6329
6330 /*
6331 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6332 * ------------------------------------------------------------
6333 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6334 * ------------------------------------------------------------
6335 */
6336 vos_mem_copy(&add_req->ucPattern[len],
6337 nla_data(tb[PARAM_IP_PACKET]),
6338 add_req->ucPtrnSize);
6339 add_req->ucPtrnSize += len;
6340
6341 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6342 add_req->ucPattern, add_req->ucPtrnSize);
6343
6344 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6345 if (ret)
6346 {
6347 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6348 goto fail;
6349 }
6350 add_req->ucPtrnId = pattern_id;
6351 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6352
6353 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6354 if (!HAL_STATUS_SUCCESS(status))
6355 {
6356 hddLog(LOGE,
6357 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6358 goto fail;
6359 }
6360
6361 EXIT();
6362 vos_mem_free(add_req);
6363 return 0;
6364
6365fail:
6366 vos_mem_free(add_req);
6367 return -EINVAL;
6368}
6369
6370/**
6371 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6372 * @adapter: adapter pointer
6373 * @hdd_ctx: hdd context
6374 * @tb: nl attributes
6375 *
6376 * This function reads the NL attributes and forms a DelTxPtrn message
6377 * posts it to SME.
6378 *
6379 */
6380static int
6381wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6382 struct nlattr **tb)
6383{
6384 struct sSirDelPeriodicTxPtrn *del_req;
6385 eHalStatus status;
6386 uint32_t request_id, ret;
6387 uint8_t pattern_id = 0;
6388
6389 /* Parse and fetch request Id */
6390 if (!tb[PARAM_REQUEST_ID])
6391 {
6392 hddLog(LOGE, FL("attr request id failed"));
6393 return -EINVAL;
6394 }
6395 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6396 if (request_id == 0)
6397 {
6398 hddLog(LOGE, FL("request_id cannot be zero"));
6399 return -EINVAL;
6400 }
6401
6402 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6403 if (ret)
6404 {
6405 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6406 return -EINVAL;
6407 }
6408
6409 del_req = vos_mem_malloc(sizeof(*del_req));
6410 if (!del_req)
6411 {
6412 hddLog(LOGE, FL("memory allocation failed"));
6413 return -ENOMEM;
6414 }
6415
6416 vos_mem_set(del_req, sizeof(*del_req), 0);
6417 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6418 VOS_MAC_ADDR_SIZE);
6419 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6420 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6421 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6422 request_id, pattern_id, del_req->ucPatternIdBitmap);
6423
6424 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6425 if (!HAL_STATUS_SUCCESS(status))
6426 {
6427 hddLog(LOGE,
6428 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6429 goto fail;
6430 }
6431
6432 EXIT();
6433 vos_mem_free(del_req);
6434 return 0;
6435
6436fail:
6437 vos_mem_free(del_req);
6438 return -EINVAL;
6439}
6440
6441
6442/**
6443 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6444 * @wiphy: Pointer to wireless phy
6445 * @wdev: Pointer to wireless device
6446 * @data: Pointer to data
6447 * @data_len: Data length
6448 *
6449 * Return: 0 on success, negative errno on failure
6450 */
6451static int
6452__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6453 struct wireless_dev *wdev,
6454 const void *data,
6455 int data_len)
6456{
6457 struct net_device *dev = wdev->netdev;
6458 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6459 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6460 struct nlattr *tb[PARAM_MAX + 1];
6461 uint8_t control;
6462 int ret;
6463 static const struct nla_policy policy[PARAM_MAX + 1] =
6464 {
6465 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6466 [PARAM_CONTROL] = { .type = NLA_U32 },
6467 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
6468 .len = VOS_MAC_ADDR_SIZE },
6469 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
6470 .len = VOS_MAC_ADDR_SIZE },
6471 [PARAM_PERIOD] = { .type = NLA_U32 },
6472 };
6473
6474 ENTER();
6475
6476 ret = wlan_hdd_validate_context(hdd_ctx);
6477 if (0 != ret)
6478 {
6479 hddLog(LOGE, FL("HDD context is not valid"));
6480 return ret;
6481 }
6482
6483 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
6484 {
6485 hddLog(LOGE,
6486 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
6487 return -ENOTSUPP;
6488 }
6489
6490 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
6491 {
6492 hddLog(LOGE, FL("Invalid ATTR"));
6493 return -EINVAL;
6494 }
6495
6496 if (!tb[PARAM_CONTROL])
6497 {
6498 hddLog(LOGE, FL("attr control failed"));
6499 return -EINVAL;
6500 }
6501 control = nla_get_u32(tb[PARAM_CONTROL]);
6502 hddLog(LOG1, FL("Control: %d"), control);
6503
6504 if (control == WLAN_START_OFFLOADED_PACKETS)
6505 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
6506 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
6507 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
6508 else
6509 {
6510 hddLog(LOGE, FL("Invalid control: %d"), control);
6511 return -EINVAL;
6512 }
6513}
6514
6515/*
6516 * done with short names for the global vendor params
6517 * used by __wlan_hdd_cfg80211_offloaded_packets()
6518 */
6519#undef PARAM_MAX
6520#undef PARAM_REQUEST_ID
6521#undef PARAM_CONTROL
6522#undef PARAM_IP_PACKET
6523#undef PARAM_SRC_MAC_ADDR
6524#undef PARAM_DST_MAC_ADDR
6525#undef PARAM_PERIOD
6526
6527/**
6528 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
6529 * @wiphy: wiphy structure pointer
6530 * @wdev: Wireless device structure pointer
6531 * @data: Pointer to the data received
6532 * @data_len: Length of @data
6533 *
6534 * Return: 0 on success; errno on failure
6535 */
6536static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6537 struct wireless_dev *wdev,
6538 const void *data,
6539 int data_len)
6540{
6541 int ret = 0;
6542
6543 vos_ssr_protect(__func__);
6544 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
6545 wdev, data, data_len);
6546 vos_ssr_unprotect(__func__);
6547
6548 return ret;
6549}
6550#endif
6551
Deepthi Gowriae6a1662015-10-12 12:59:37 +05306552static const struct
6553nla_policy
6554qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306555 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6556 .type = NLA_BINARY,
6557 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05306558};
6559
6560/**
6561 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
6562 * get link properties like nss, rate flags and operating frequency for
6563 * the connection with the given peer.
6564 * @wiphy: WIPHY structure pointer
6565 * @wdev: Wireless device structure pointer
6566 * @data: Pointer to the data received
6567 * @data_len: Length of the data received
6568 *
6569 * This function return the above link properties on success.
6570 *
6571 * Return: 0 on success and errno on failure
6572 */
6573static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
6574 struct wireless_dev *wdev,
6575 const void *data,
6576 int data_len)
6577{
6578 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6579 struct net_device *dev = wdev->netdev;
6580 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6581 hdd_station_ctx_t *hdd_sta_ctx;
6582 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
6583 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
6584 uint32_t sta_id;
6585 struct sk_buff *reply_skb;
6586 uint32_t rate_flags = 0;
6587 uint8_t nss;
6588 uint8_t final_rate_flags = 0;
6589 uint32_t freq;
6590 v_CONTEXT_t pVosContext = NULL;
6591 ptSapContext pSapCtx = NULL;
6592
6593 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
6594 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
6595 return -EINVAL;
6596 }
6597
6598 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6599 qca_wlan_vendor_attr_policy)) {
6600 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
6601 return -EINVAL;
6602 }
6603
6604 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6605 hddLog(VOS_TRACE_LEVEL_ERROR,
6606 FL("Attribute peerMac not provided for mode=%d"),
6607 adapter->device_mode);
6608 return -EINVAL;
6609 }
6610
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05306611 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
6612 hddLog(VOS_TRACE_LEVEL_ERROR,
6613 FL("Attribute peerMac is invalid=%d"),
6614 adapter->device_mode);
6615 return -EINVAL;
6616 }
6617
Deepthi Gowriae6a1662015-10-12 12:59:37 +05306618 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6619 sizeof(peer_mac));
6620 hddLog(VOS_TRACE_LEVEL_INFO,
6621 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
6622 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
6623
6624 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
6625 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
6626 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
6627 if ((hdd_sta_ctx->conn_info.connState !=
6628 eConnectionState_Associated) ||
6629 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
6630 VOS_MAC_ADDRESS_LEN)) {
6631 hddLog(VOS_TRACE_LEVEL_ERROR,
6632 FL("Not Associated to mac "MAC_ADDRESS_STR),
6633 MAC_ADDR_ARRAY(peer_mac));
6634 return -EINVAL;
6635 }
6636
6637 nss = 1; //pronto supports only one spatial stream
6638 freq = vos_chan_to_freq(
6639 hdd_sta_ctx->conn_info.operationChannel);
6640 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
6641
6642 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
6643 adapter->device_mode == WLAN_HDD_SOFTAP) {
6644
6645 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
6646 pSapCtx = VOS_GET_SAP_CB(pVosContext);
6647 if(pSapCtx == NULL){
6648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6649 FL("psapCtx is NULL"));
6650 return -ENOENT;
6651 }
6652
6653
6654 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
6655 if (pSapCtx->aStaInfo[sta_id].isUsed &&
6656 !vos_is_macaddr_broadcast(
6657 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
6658 vos_mem_compare(
6659 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
6660 peer_mac, VOS_MAC_ADDRESS_LEN))
6661 break;
6662 }
6663
6664 if (WLAN_MAX_STA_COUNT == sta_id) {
6665 hddLog(VOS_TRACE_LEVEL_ERROR,
6666 FL("No active peer with mac="MAC_ADDRESS_STR),
6667 MAC_ADDR_ARRAY(peer_mac));
6668 return -EINVAL;
6669 }
6670
6671 nss = 1; //pronto supports only one spatial stream
6672 freq = vos_chan_to_freq(
6673 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
6674 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
6675 } else {
6676 hddLog(VOS_TRACE_LEVEL_ERROR,
6677 FL("Not Associated! with mac"MAC_ADDRESS_STR),
6678 MAC_ADDR_ARRAY(peer_mac));
6679 return -EINVAL;
6680 }
6681
6682 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
6683 if (rate_flags & eHAL_TX_RATE_VHT80) {
6684 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
6685 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
6686 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
6687 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
6688 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6689 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
6690 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
6691 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
6692 final_rate_flags |= RATE_INFO_FLAGS_MCS;
6693 if (rate_flags & eHAL_TX_RATE_HT40)
6694 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6695 }
6696
6697 if (rate_flags & eHAL_TX_RATE_SGI) {
6698 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
6699 final_rate_flags |= RATE_INFO_FLAGS_MCS;
6700 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
6701 }
6702 }
6703
6704 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6705 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
6706
6707 if (NULL == reply_skb) {
6708 hddLog(VOS_TRACE_LEVEL_ERROR,
6709 FL("getLinkProperties: skb alloc failed"));
6710 return -EINVAL;
6711 }
6712
6713 if (nla_put_u8(reply_skb,
6714 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
6715 nss) ||
6716 nla_put_u8(reply_skb,
6717 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
6718 final_rate_flags) ||
6719 nla_put_u32(reply_skb,
6720 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
6721 freq)) {
6722 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
6723 kfree_skb(reply_skb);
6724 return -EINVAL;
6725 }
6726
6727 return cfg80211_vendor_cmd_reply(reply_skb);
6728}
6729
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05306730#define BEACON_MISS_THRESH_2_4 \
6731 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
6732#define BEACON_MISS_THRESH_5_0 \
6733 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05306734#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
6735#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
6736#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
6737#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05306738#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
6739 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05306740
6741/**
6742 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
6743 * vendor command
6744 *
6745 * @wiphy: wiphy device pointer
6746 * @wdev: wireless device pointer
6747 * @data: Vendor command data buffer
6748 * @data_len: Buffer length
6749 *
6750 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
6751 *
6752 * Return: EOK or other error codes.
6753 */
6754
6755static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
6756 struct wireless_dev *wdev,
6757 const void *data,
6758 int data_len)
6759{
6760 struct net_device *dev = wdev->netdev;
6761 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6762 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6763 hdd_station_ctx_t *pHddStaCtx;
6764 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
6765 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05306766 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05306767 eHalStatus status;
6768 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05306769 uint8_t hb_thresh_val;
6770
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05306771 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
6772 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
6773 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05306774 [PARAM_GUARD_TIME] = { .type = NLA_U32},
6775 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
6776 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05306777 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
6778 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05306779 };
6780
6781 ENTER();
6782
6783 if (VOS_FTM_MODE == hdd_get_conparam()) {
6784 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6785 return -EINVAL;
6786 }
6787
6788 ret_val = wlan_hdd_validate_context(pHddCtx);
6789 if (ret_val) {
6790 return ret_val;
6791 }
6792
6793 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6794
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05306795 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
6796 hddLog(LOGE, FL("Invalid ATTR"));
6797 return -EINVAL;
6798 }
6799
6800 /* check the Wifi Capability */
6801 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
6802 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
6803 {
6804 hddLog(VOS_TRACE_LEVEL_ERROR,
6805 FL("WIFICONFIG not supported by Firmware"));
6806 return -EINVAL;
6807 }
6808
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05306809 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
6810 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
6811 modifyRoamParamsReq.value =
6812 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
6813
6814 if (eHAL_STATUS_SUCCESS !=
6815 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
6816 {
6817 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
6818 ret_val = -EINVAL;
6819 }
6820 return ret_val;
6821 }
6822
6823 /* Moved this down in order to provide provision to set beacon
6824 * miss penalty count irrespective of connection state.
6825 */
6826 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6827 hddLog(LOGE, FL("Not in Connected state!"));
6828 return -ENOTSUPP;
6829 }
6830
6831 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05306832
6833 if (!pReq) {
6834 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6835 "%s: Not able to allocate memory for tSetWifiConfigParams",
6836 __func__);
6837 return eHAL_STATUS_E_MALLOC_FAILED;
6838 }
6839
6840 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
6841
6842 pReq->sessionId = pAdapter->sessionId;
6843 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6844
6845 if (tb[PARAM_MODULATED_DTIM]) {
6846 pReq->paramValue = nla_get_u32(
6847 tb[PARAM_MODULATED_DTIM]);
6848 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
6849 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05306850 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05306851 hdd_set_pwrparams(pHddCtx);
6852 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
6853 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
6854
6855 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
6856 iw_full_power_cbfn, pAdapter,
6857 eSME_FULL_PWR_NEEDED_BY_HDD);
6858 }
6859 else
6860 {
6861 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
6862 }
6863 }
6864
6865 if (tb[PARAM_STATS_AVG_FACTOR]) {
6866 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
6867 pReq->paramValue = nla_get_u16(
6868 tb[PARAM_STATS_AVG_FACTOR]);
6869 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
6870 pReq->paramType, pReq->paramValue);
6871 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
6872
6873 if (eHAL_STATUS_SUCCESS != status)
6874 {
6875 vos_mem_free(pReq);
6876 pReq = NULL;
6877 ret_val = -EPERM;
6878 return ret_val;
6879 }
6880 }
6881
6882
6883 if (tb[PARAM_GUARD_TIME]) {
6884 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
6885 pReq->paramValue = nla_get_u32(
6886 tb[PARAM_GUARD_TIME]);
6887 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
6888 pReq->paramType, pReq->paramValue);
6889 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
6890
6891 if (eHAL_STATUS_SUCCESS != status)
6892 {
6893 vos_mem_free(pReq);
6894 pReq = NULL;
6895 ret_val = -EPERM;
6896 return ret_val;
6897 }
6898
6899 }
6900
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05306901 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
6902 hb_thresh_val = nla_get_u8(
6903 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
6904
6905 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
6906 hb_thresh_val);
6907 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6908 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
6909 NULL, eANI_BOOLEAN_FALSE);
6910
6911 status = sme_update_hb_threshold(
6912 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
6913 WNI_CFG_HEART_BEAT_THRESHOLD,
6914 hb_thresh_val, eCSR_BAND_24);
6915 if (eHAL_STATUS_SUCCESS != status) {
6916 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
6917 vos_mem_free(pReq);
6918 pReq = NULL;
6919 return -EPERM;
6920 }
6921 }
6922
6923 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
6924 hb_thresh_val = nla_get_u8(
6925 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
6926
6927 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
6928 hb_thresh_val);
6929 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6930 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
6931 NULL, eANI_BOOLEAN_FALSE);
6932
6933 status = sme_update_hb_threshold(
6934 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
6935 WNI_CFG_HEART_BEAT_THRESHOLD,
6936 hb_thresh_val, eCSR_BAND_5G);
6937 if (eHAL_STATUS_SUCCESS != status) {
6938 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
6939 vos_mem_free(pReq);
6940 pReq = NULL;
6941 return -EPERM;
6942 }
6943 }
6944
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05306945 EXIT();
6946 return ret_val;
6947}
6948
6949/**
6950 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
6951 * vendor command
6952 *
6953 * @wiphy: wiphy device pointer
6954 * @wdev: wireless device pointer
6955 * @data: Vendor command data buffer
6956 * @data_len: Buffer length
6957 *
6958 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
6959 *
6960 * Return: EOK or other error codes.
6961 */
6962static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
6963 struct wireless_dev *wdev,
6964 const void *data,
6965 int data_len)
6966{
6967 int ret;
6968
6969 vos_ssr_protect(__func__);
6970 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
6971 data, data_len);
6972 vos_ssr_unprotect(__func__);
6973
6974 return ret;
6975}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05306976
6977/*
6978 * define short names for the global vendor params
6979 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
6980 */
6981#define STATS_SET_INVALID \
6982 QCA_ATTR_NUD_STATS_SET_INVALID
6983#define STATS_SET_START \
6984 QCA_ATTR_NUD_STATS_SET_START
6985#define STATS_GW_IPV4 \
6986 QCA_ATTR_NUD_STATS_GW_IPV4
6987#define STATS_SET_MAX \
6988 QCA_ATTR_NUD_STATS_SET_MAX
6989
6990const struct nla_policy
6991qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
6992{
6993 [STATS_SET_START] = {.type = NLA_FLAG },
6994 [STATS_GW_IPV4] = {.type = NLA_U32 },
6995};
6996
6997/**
6998 * hdd_set_nud_stats_cb() - hdd callback api to get status
6999 * @data: pointer to adapter
7000 * @rsp: status
7001 *
7002 * Return: None
7003 */
7004static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
7005{
7006
7007 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7008
7009 if (NULL == adapter)
7010 return;
7011
7012 if (VOS_STATUS_SUCCESS == rsp) {
7013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7014 "%s success received STATS_SET_START", __func__);
7015 } else {
7016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7017 "%s STATS_SET_START Failed!!", __func__);
7018 }
7019 return;
7020}
7021
7022/**
7023 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7024 * @wiphy: pointer to wireless wiphy structure.
7025 * @wdev: pointer to wireless_dev structure.
7026 * @data: pointer to apfind configuration data.
7027 * @data_len: the length in byte of apfind data.
7028 *
7029 * This is called when wlan driver needs to send arp stats to
7030 * firmware.
7031 *
7032 * Return: An error code or 0 on success.
7033 */
7034static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7035 struct wireless_dev *wdev,
7036 const void *data, int data_len)
7037{
7038 struct nlattr *tb[STATS_SET_MAX + 1];
7039 struct net_device *dev = wdev->netdev;
7040 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7041 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05307042 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307043 setArpStatsParams arp_stats_params;
7044 int err = 0;
7045
7046 ENTER();
7047
7048 err = wlan_hdd_validate_context(hdd_ctx);
7049 if (0 != err)
7050 return err;
7051
7052 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
7053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7054 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
7055 return -EINVAL;
7056 }
7057
7058 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
7059 qca_wlan_vendor_set_nud_stats);
7060 if (err)
7061 {
7062 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7063 "%s STATS_SET_START ATTR", __func__);
7064 return err;
7065 }
7066
7067 if (tb[STATS_SET_START])
7068 {
7069 if (!tb[STATS_GW_IPV4]) {
7070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7071 "%s STATS_SET_START CMD", __func__);
7072 return -EINVAL;
7073 }
7074 arp_stats_params.flag = true;
7075 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
7076 } else {
7077 arp_stats_params.flag = false;
7078 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05307079 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307080 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7081 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05307082 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
7083 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307084
7085 arp_stats_params.pkt_type = 1; // ARP packet type
7086
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05307087 if (arp_stats_params.flag) {
7088 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
7089 WLANTL_SetARPFWDatapath(pVosContext, true);
7090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7091 "%s Set FW in data path for ARP with tgt IP :%d",
7092 __func__, hdd_ctx->track_arp_ip);
7093 }
7094 else {
7095 WLANTL_SetARPFWDatapath(pVosContext, false);
7096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7097 "%s Remove FW from data path", __func__);
7098 }
7099
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307100 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
7101 arp_stats_params.data_ctx = adapter;
7102
7103 if (eHAL_STATUS_SUCCESS !=
7104 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
7105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7106 "%s STATS_SET_START CMD Failed!!", __func__);
7107 return -EINVAL;
7108 }
7109
7110 EXIT();
7111
7112 return err;
7113}
7114
7115/**
7116 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7117 * @wiphy: pointer to wireless wiphy structure.
7118 * @wdev: pointer to wireless_dev structure.
7119 * @data: pointer to apfind configuration data.
7120 * @data_len: the length in byte of apfind data.
7121 *
7122 * This is called when wlan driver needs to send arp stats to
7123 * firmware.
7124 *
7125 * Return: An error code or 0 on success.
7126 */
7127static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7128 struct wireless_dev *wdev,
7129 const void *data, int data_len)
7130{
7131 int ret;
7132
7133 vos_ssr_protect(__func__);
7134 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
7135 vos_ssr_unprotect(__func__);
7136
7137 return ret;
7138}
7139#undef STATS_SET_INVALID
7140#undef STATS_SET_START
7141#undef STATS_GW_IPV4
7142#undef STATS_SET_MAX
7143
7144/*
7145 * define short names for the global vendor params
7146 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7147 */
7148#define STATS_GET_INVALID \
7149 QCA_ATTR_NUD_STATS_SET_INVALID
7150#define COUNT_FROM_NETDEV \
7151 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
7152#define COUNT_TO_LOWER_MAC \
7153 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
7154#define RX_COUNT_BY_LOWER_MAC \
7155 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
7156#define COUNT_TX_SUCCESS \
7157 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
7158#define RSP_RX_COUNT_BY_LOWER_MAC \
7159 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
7160#define RSP_RX_COUNT_BY_UPPER_MAC \
7161 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
7162#define RSP_COUNT_TO_NETDEV \
7163 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
7164#define RSP_COUNT_OUT_OF_ORDER_DROP \
7165 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
7166#define AP_LINK_ACTIVE \
7167 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
7168#define AP_LINK_DAD \
7169 QCA_ATTR_NUD_STATS_AP_LINK_DAD
7170#define STATS_GET_MAX \
7171 QCA_ATTR_NUD_STATS_GET_MAX
7172
7173const struct nla_policy
7174qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
7175{
7176 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
7177 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
7178 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
7179 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
7180 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
7181 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
7182 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
7183 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
7184 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
7185 [AP_LINK_DAD] = {.type = NLA_FLAG },
7186};
7187
7188static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
7189{
7190
7191 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7192 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7193 struct hdd_nud_stats_context *context;
7194 int status;
7195
7196 ENTER();
7197
7198 if (NULL == adapter)
7199 return;
7200
7201 status = wlan_hdd_validate_context(hdd_ctx);
7202 if (0 != status) {
7203 return;
7204 }
7205
7206 if (!rsp) {
7207 hddLog(LOGE, FL("data is null"));
7208 return;
7209 }
7210
7211 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
7212 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
7213 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
7214 adapter->dad |= rsp->dad;
7215
7216 spin_lock(&hdd_context_lock);
7217 context = &hdd_ctx->nud_stats_context;
7218 complete(&context->response_event);
7219 spin_unlock(&hdd_context_lock);
7220
7221 return;
7222}
7223static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
7224 struct wireless_dev *wdev,
7225 const void *data, int data_len)
7226{
7227 int err = 0;
7228 unsigned long rc;
7229 struct hdd_nud_stats_context *context;
7230 struct net_device *dev = wdev->netdev;
7231 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7232 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7233 getArpStatsParams arp_stats_params;
7234 struct sk_buff *skb;
7235
7236 ENTER();
7237
7238 err = wlan_hdd_validate_context(hdd_ctx);
7239 if (0 != err)
7240 return err;
7241
7242 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
7243 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
7244 arp_stats_params.data_ctx = adapter;
7245
7246 spin_lock(&hdd_context_lock);
7247 context = &hdd_ctx->nud_stats_context;
7248 INIT_COMPLETION(context->response_event);
7249 spin_unlock(&hdd_context_lock);
7250
7251 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
7252 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7253 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
7254 return -EINVAL;
7255 }
7256
7257 if (eHAL_STATUS_SUCCESS !=
7258 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
7259 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7260 "%s STATS_SET_START CMD Failed!!", __func__);
7261 return -EINVAL;
7262 }
7263
7264 rc = wait_for_completion_timeout(&context->response_event,
7265 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
7266 if (!rc)
7267 {
7268 hddLog(LOGE,
7269 FL("Target response timed out request "));
7270 return -ETIMEDOUT;
7271 }
7272
7273 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7274 WLAN_NUD_STATS_LEN);
7275 if (!skb)
7276 {
7277 hddLog(VOS_TRACE_LEVEL_ERROR,
7278 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
7279 __func__);
7280 return -ENOMEM;
7281 }
7282
7283 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
7284 adapter->hdd_stats.hddArpStats.txCount) ||
7285 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
7286 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
7287 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
7288 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
7289 nla_put_u16(skb, COUNT_TX_SUCCESS,
7290 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
7291 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
7292 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
7293 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
7294 adapter->hdd_stats.hddArpStats.rxCount) ||
7295 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
7296 adapter->hdd_stats.hddArpStats.rxDelivered) ||
7297 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
7298 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
7299 hddLog(LOGE, FL("nla put fail"));
7300 kfree_skb(skb);
7301 return -EINVAL;
7302 }
7303 if (adapter->con_status)
7304 nla_put_flag(skb, AP_LINK_ACTIVE);
7305 if (adapter->dad)
7306 nla_put_flag(skb, AP_LINK_DAD);
7307
7308 cfg80211_vendor_cmd_reply(skb);
7309 return err;
7310}
7311
7312static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
7313 struct wireless_dev *wdev,
7314 const void *data, int data_len)
7315{
7316 int ret;
7317
7318 vos_ssr_protect(__func__);
7319 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
7320 vos_ssr_unprotect(__func__);
7321
7322 return ret;
7323}
7324
7325#undef QCA_ATTR_NUD_STATS_SET_INVALID
7326#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
7327#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
7328#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
7329#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
7330#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
7331#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
7332#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
7333#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
7334#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
7335#undef QCA_ATTR_NUD_STATS_GET_MAX
7336
7337
7338
Kapil Guptaee33bf12016-12-20 18:27:37 +05307339#ifdef WLAN_FEATURE_APFIND
7340/**
7341 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7342 * @wiphy: pointer to wireless wiphy structure.
7343 * @wdev: pointer to wireless_dev structure.
7344 * @data: pointer to apfind configuration data.
7345 * @data_len: the length in byte of apfind data.
7346 *
7347 * This is called when wlan driver needs to send APFIND configurations to
7348 * firmware.
7349 *
7350 * Return: An error code or 0 on success.
7351 */
7352static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7353 struct wireless_dev *wdev,
7354 const void *data, int data_len)
7355{
7356 struct sme_ap_find_request_req apfind_req;
7357 VOS_STATUS status;
7358 int ret_val;
7359 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7360
7361 ENTER();
7362
7363 ret_val = wlan_hdd_validate_context(hdd_ctx);
7364 if (ret_val)
7365 return ret_val;
7366
7367 if (VOS_FTM_MODE == hdd_get_conparam()) {
7368 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7369 return -EPERM;
7370 }
7371
7372 apfind_req.request_data_len = data_len;
7373 apfind_req.request_data = data;
7374
7375 status = sme_apfind_set_cmd(&apfind_req);
7376 if (VOS_STATUS_SUCCESS != status) {
7377 ret_val = -EIO;
7378 }
7379 return ret_val;
7380}
7381
7382/**
7383 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7384 * @wiphy: pointer to wireless wiphy structure.
7385 * @wdev: pointer to wireless_dev structure.
7386 * @data: pointer to apfind configuration data.
7387 * @data_len: the length in byte of apfind data.
7388 *
7389 * This is called when wlan driver needs to send APFIND configurations to
7390 * firmware.
7391 *
7392 * Return: An error code or 0 on success.
7393 */
7394static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7395 struct wireless_dev *wdev,
7396 const void *data, int data_len)
7397{
7398 int ret;
7399
7400 vos_ssr_protect(__func__);
7401 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
7402 vos_ssr_unprotect(__func__);
7403
7404 return ret;
7405}
7406#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307407const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7408{
Mukul Sharma2a271632014-10-13 14:59:01 +05307409 {
7410 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7411 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7412 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7413 WIPHY_VENDOR_CMD_NEED_NETDEV |
7414 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307415 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307416 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307417
7418 {
7419 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7420 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7421 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7422 WIPHY_VENDOR_CMD_NEED_NETDEV |
7423 WIPHY_VENDOR_CMD_NEED_RUNNING,
7424 .doit = wlan_hdd_cfg80211_nan_request
7425 },
7426
Sunil Duttc69bccb2014-05-26 21:30:20 +05307427#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7428 {
7429 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7430 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7431 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7432 WIPHY_VENDOR_CMD_NEED_NETDEV |
7433 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307434 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307435 },
7436
7437 {
7438 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7439 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7440 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7441 WIPHY_VENDOR_CMD_NEED_NETDEV |
7442 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307443 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307444 },
7445
7446 {
7447 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7448 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7449 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7450 WIPHY_VENDOR_CMD_NEED_NETDEV |
7451 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307452 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307453 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307454#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307455#ifdef WLAN_FEATURE_EXTSCAN
7456 {
7457 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7458 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7459 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7460 WIPHY_VENDOR_CMD_NEED_NETDEV |
7461 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307462 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307463 },
7464 {
7465 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7466 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7467 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7468 WIPHY_VENDOR_CMD_NEED_NETDEV |
7469 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307470 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307471 },
7472 {
7473 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7474 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7475 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7476 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307477 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05307478 },
7479 {
7480 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7481 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
7482 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7483 WIPHY_VENDOR_CMD_NEED_NETDEV |
7484 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307485 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05307486 },
7487 {
7488 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7489 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
7490 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7491 WIPHY_VENDOR_CMD_NEED_NETDEV |
7492 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307493 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05307494 },
7495 {
7496 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7497 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
7498 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7499 WIPHY_VENDOR_CMD_NEED_NETDEV |
7500 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307501 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307502 },
7503 {
7504 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7505 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
7506 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7507 WIPHY_VENDOR_CMD_NEED_NETDEV |
7508 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307509 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307510 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307511#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307512/*EXT TDLS*/
7513 {
7514 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7515 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
7516 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7517 WIPHY_VENDOR_CMD_NEED_NETDEV |
7518 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307519 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05307520 },
7521 {
7522 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7523 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
7524 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7525 WIPHY_VENDOR_CMD_NEED_NETDEV |
7526 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307527 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05307528 },
7529 {
7530 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7531 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
7532 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7533 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307534 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05307535 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05307536 {
7537 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7538 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
7539 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7540 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307541 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05307542 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05307543 {
7544 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7545 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
7546 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7547 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307548 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05307549 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307550 {
7551 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7552 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
7553 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7554 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307555 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307556 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307557 {
7558 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7559 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
7560 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7561 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307562 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307563 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307564 {
7565 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05307566 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
7567 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7568 WIPHY_VENDOR_CMD_NEED_NETDEV |
7569 WIPHY_VENDOR_CMD_NEED_RUNNING,
7570 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
7571 },
7572 {
7573 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307574 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
7575 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7576 WIPHY_VENDOR_CMD_NEED_NETDEV |
7577 WIPHY_VENDOR_CMD_NEED_RUNNING,
7578 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05307579 },
7580 {
7581 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7582 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
7583 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7584 WIPHY_VENDOR_CMD_NEED_NETDEV,
7585 .doit = wlan_hdd_cfg80211_wifi_logger_start
7586 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05307587 {
7588 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7589 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
7590 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7591 WIPHY_VENDOR_CMD_NEED_NETDEV|
7592 WIPHY_VENDOR_CMD_NEED_RUNNING,
7593 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05307594 },
7595 {
7596 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7597 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
7598 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7599 WIPHY_VENDOR_CMD_NEED_NETDEV |
7600 WIPHY_VENDOR_CMD_NEED_RUNNING,
7601 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307602 },
7603 {
7604 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7605 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
7606 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7607 WIPHY_VENDOR_CMD_NEED_NETDEV |
7608 WIPHY_VENDOR_CMD_NEED_RUNNING,
7609 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307610 },
7611#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7612 {
7613 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7614 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
7615 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7616 WIPHY_VENDOR_CMD_NEED_NETDEV |
7617 WIPHY_VENDOR_CMD_NEED_RUNNING,
7618 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307619 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307620#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307621 {
7622 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7623 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
7624 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7625 WIPHY_VENDOR_CMD_NEED_NETDEV |
7626 WIPHY_VENDOR_CMD_NEED_RUNNING,
7627 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307628 },
7629 {
7630 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7631 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
7632 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7633 WIPHY_VENDOR_CMD_NEED_NETDEV |
7634 WIPHY_VENDOR_CMD_NEED_RUNNING,
7635 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05307636 },
7637#ifdef WLAN_FEATURE_APFIND
7638 {
7639 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7640 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
7641 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7642 WIPHY_VENDOR_CMD_NEED_NETDEV,
7643 .doit = wlan_hdd_cfg80211_apfind_cmd
7644 },
7645#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307646 {
7647 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7648 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
7649 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7650 WIPHY_VENDOR_CMD_NEED_NETDEV |
7651 WIPHY_VENDOR_CMD_NEED_RUNNING,
7652 .doit = wlan_hdd_cfg80211_set_nud_stats
7653 },
7654 {
7655 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7656 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
7657 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7658 WIPHY_VENDOR_CMD_NEED_NETDEV |
7659 WIPHY_VENDOR_CMD_NEED_RUNNING,
7660 .doit = wlan_hdd_cfg80211_get_nud_stats
7661 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307662};
7663
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007664/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307665static const
7666struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007667{
7668#ifdef FEATURE_WLAN_CH_AVOID
7669 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05307670 .vendor_id = QCA_NL80211_VENDOR_ID,
7671 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007672 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307673#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
7674#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7675 {
7676 /* Index = 1*/
7677 .vendor_id = QCA_NL80211_VENDOR_ID,
7678 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
7679 },
7680 {
7681 /* Index = 2*/
7682 .vendor_id = QCA_NL80211_VENDOR_ID,
7683 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
7684 },
7685 {
7686 /* Index = 3*/
7687 .vendor_id = QCA_NL80211_VENDOR_ID,
7688 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
7689 },
7690 {
7691 /* Index = 4*/
7692 .vendor_id = QCA_NL80211_VENDOR_ID,
7693 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
7694 },
7695 {
7696 /* Index = 5*/
7697 .vendor_id = QCA_NL80211_VENDOR_ID,
7698 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
7699 },
7700 {
7701 /* Index = 6*/
7702 .vendor_id = QCA_NL80211_VENDOR_ID,
7703 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
7704 },
7705#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307706#ifdef WLAN_FEATURE_EXTSCAN
7707 {
7708 .vendor_id = QCA_NL80211_VENDOR_ID,
7709 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
7710 },
7711 {
7712 .vendor_id = QCA_NL80211_VENDOR_ID,
7713 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
7714 },
7715 {
7716 .vendor_id = QCA_NL80211_VENDOR_ID,
7717 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
7718 },
7719 {
7720 .vendor_id = QCA_NL80211_VENDOR_ID,
7721 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
7722 },
7723 {
7724 .vendor_id = QCA_NL80211_VENDOR_ID,
7725 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
7726 },
7727 {
7728 .vendor_id = QCA_NL80211_VENDOR_ID,
7729 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
7730 },
7731 {
7732 .vendor_id = QCA_NL80211_VENDOR_ID,
7733 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
7734 },
7735 {
7736 .vendor_id = QCA_NL80211_VENDOR_ID,
7737 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
7738 },
7739 {
7740 .vendor_id = QCA_NL80211_VENDOR_ID,
7741 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
7742 },
7743 {
7744 .vendor_id = QCA_NL80211_VENDOR_ID,
7745 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
7746 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307747#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307748/*EXT TDLS*/
7749 {
7750 .vendor_id = QCA_NL80211_VENDOR_ID,
7751 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
7752 },
c_manjeecfd1efb2015-09-25 19:32:34 +05307753 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
7754 .vendor_id = QCA_NL80211_VENDOR_ID,
7755 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
7756 },
7757
Srinivas Dasari030bad32015-02-18 23:23:54 +05307758
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05307759 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05307760 .vendor_id = QCA_NL80211_VENDOR_ID,
7761 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
7762 },
7763
Sushant Kaushik084f6592015-09-10 13:11:56 +05307764 {
7765 .vendor_id = QCA_NL80211_VENDOR_ID,
7766 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307767 },
7768 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
7769 .vendor_id = QCA_NL80211_VENDOR_ID,
7770 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
7771 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05307772 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
7773 .vendor_id = QCA_NL80211_VENDOR_ID,
7774 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
7775 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307776 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
7777 .vendor_id = QCA_NL80211_VENDOR_ID,
7778 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
7779 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007780};
7781
Jeff Johnson295189b2012-06-20 16:38:30 -07007782/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307783 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307784 * This function is called by hdd_wlan_startup()
7785 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307786 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07007787 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307788struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07007789{
7790 struct wiphy *wiphy;
7791 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307792 /*
7793 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07007794 */
7795 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
7796
7797 if (!wiphy)
7798 {
7799 /* Print error and jump into err label and free the memory */
7800 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
7801 return NULL;
7802 }
7803
Sunil Duttc69bccb2014-05-26 21:30:20 +05307804
Jeff Johnson295189b2012-06-20 16:38:30 -07007805 return wiphy;
7806}
7807
Anurag Chouhan343af7e2016-12-16 13:11:19 +05307808#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
7809 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
7810/**
7811 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
7812 * @wiphy: pointer to wiphy
7813 * @config: pointer to config
7814 *
7815 * Return: None
7816 */
7817static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
7818 hdd_config_t *config)
7819{
7820 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
7821 if (config->max_sched_scan_plan_interval)
7822 wiphy->max_sched_scan_plan_interval =
7823 config->max_sched_scan_plan_interval;
7824 if (config->max_sched_scan_plan_iterations)
7825 wiphy->max_sched_scan_plan_iterations =
7826 config->max_sched_scan_plan_iterations;
7827}
7828#else
7829static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
7830 hdd_config_t *config)
7831{
7832}
7833#endif
7834
Jeff Johnson295189b2012-06-20 16:38:30 -07007835/*
7836 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307837 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07007838 * private ioctl to change the band value
7839 */
7840int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
7841{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307842 int i, j;
7843 eNVChannelEnabledType channelEnabledState;
7844
Jeff Johnsone7245742012-09-05 17:12:55 -07007845 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307846
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307847 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007848 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307849
7850 if (NULL == wiphy->bands[i])
7851 {
7852 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
7853 __func__, i);
7854 continue;
7855 }
7856
7857 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7858 {
7859 struct ieee80211_supported_band *band = wiphy->bands[i];
7860
7861 channelEnabledState = vos_nv_getChannelEnabledState(
7862 band->channels[j].hw_value);
7863
7864 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
7865 {
Abhishek Singh678227a2014-11-04 10:52:38 +05307866 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307867 continue;
7868 }
7869 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
7870 {
7871 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7872 continue;
7873 }
7874
7875 if (NV_CHANNEL_DISABLE == channelEnabledState ||
7876 NV_CHANNEL_INVALID == channelEnabledState)
7877 {
7878 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7879 }
7880 else if (NV_CHANNEL_DFS == channelEnabledState)
7881 {
7882 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7883 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
7884 }
7885 else
7886 {
7887 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
7888 |IEEE80211_CHAN_RADAR);
7889 }
7890 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007891 }
7892 return 0;
7893}
7894/*
7895 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307896 * This function is called by hdd_wlan_startup()
7897 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07007898 * This function is used to initialize and register wiphy structure.
7899 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307900int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007901 struct wiphy *wiphy,
7902 hdd_config_t *pCfg
7903 )
7904{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307905 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307906 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7907
Jeff Johnsone7245742012-09-05 17:12:55 -07007908 ENTER();
7909
Jeff Johnson295189b2012-06-20 16:38:30 -07007910 /* Now bind the underlying wlan device with wiphy */
7911 set_wiphy_dev(wiphy, dev);
7912
7913 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007914
Kiet Lam6c583332013-10-14 05:37:09 +05307915#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007916 /* the flag for the other case would be initialzed in
7917 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05307918#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7919 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
7920#else
Amar Singhal0a402232013-10-11 20:57:16 -07007921 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05307922#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05307923#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007924
Amar Singhalfddc28c2013-09-05 13:03:40 -07007925 /* This will disable updating of NL channels from passive to
7926 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307927#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7928 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
7929#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07007930 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307931#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07007932
Amar Singhala49cbc52013-10-08 18:37:44 -07007933
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007934#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07007935 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
7936 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
7937 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07007938 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307939#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05307940 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307941#else
7942 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
7943#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007944#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007945
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007946#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007947 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08007948#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007949 || pCfg->isFastRoamIniFeatureEnabled
7950#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007951#ifdef FEATURE_WLAN_ESE
7952 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007953#endif
7954 )
7955 {
7956 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7957 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08007958#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007959#ifdef FEATURE_WLAN_TDLS
7960 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
7961 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
7962#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307963#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05307964 if (pCfg->configPNOScanSupport)
7965 {
7966 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
7967 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
7968 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
7969 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
7970 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307971#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007972
Abhishek Singh10d85972015-04-17 10:27:23 +05307973#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7974 wiphy->features |= NL80211_FEATURE_HT_IBSS;
7975#endif
7976
Amar Singhalfddc28c2013-09-05 13:03:40 -07007977#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007978 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
7979 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07007980 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007981 driver need to determine what to do with both
7982 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07007983
7984 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07007985#else
7986 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007987#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007988
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307989 wiphy->max_scan_ssids = MAX_SCAN_SSID;
7990
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05307991 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07007992
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307993 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
7994
Jeff Johnson295189b2012-06-20 16:38:30 -07007995 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05307996 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
7997 | BIT(NL80211_IFTYPE_ADHOC)
7998 | BIT(NL80211_IFTYPE_P2P_CLIENT)
7999 | BIT(NL80211_IFTYPE_P2P_GO)
8000 | BIT(NL80211_IFTYPE_AP);
8001
8002 if (VOS_MONITOR_MODE == hdd_get_conparam())
8003 {
8004 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
8005 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008006
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308007 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008008 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308009#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8010 if( pCfg->enableMCC )
8011 {
8012 /* Currently, supports up to two channels */
8013 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008014
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308015 if( !pCfg->allowMCCGODiffBI )
8016 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008017
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308018 }
8019 wiphy->iface_combinations = &wlan_hdd_iface_combination;
8020 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008021#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308022 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008023
Jeff Johnson295189b2012-06-20 16:38:30 -07008024 /* Before registering we need to update the ht capabilitied based
8025 * on ini values*/
8026 if( !pCfg->ShortGI20MhzEnable )
8027 {
8028 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8029 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008030 }
8031
8032 if( !pCfg->ShortGI40MhzEnable )
8033 {
8034 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8035 }
8036
8037 if( !pCfg->nChannelBondingMode5GHz )
8038 {
8039 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8040 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308041 /*
8042 * In case of static linked driver at the time of driver unload,
8043 * module exit doesn't happens. Module cleanup helps in cleaning
8044 * of static memory.
8045 * If driver load happens statically, at the time of driver unload,
8046 * wiphy flags don't get reset because of static memory.
8047 * It's better not to store channel in static memory.
8048 */
8049 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8050 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8051 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8052 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8053 {
8054 hddLog(VOS_TRACE_LEVEL_ERROR,
8055 FL("Not enough memory to allocate channels"));
8056 return -ENOMEM;
8057 }
8058 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8059 &hdd_channels_2_4_GHZ[0],
8060 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008061
Agrawal Ashish97dec502015-11-26 20:20:58 +05308062 if (true == hdd_is_5g_supported(pHddCtx))
8063 {
8064 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8065 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8066 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8067 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8068 {
8069 hddLog(VOS_TRACE_LEVEL_ERROR,
8070 FL("Not enough memory to allocate channels"));
8071 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8072 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8073 return -ENOMEM;
8074 }
8075 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8076 &hdd_channels_5_GHZ[0],
8077 sizeof(hdd_channels_5_GHZ));
8078 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308079
8080 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8081 {
8082
8083 if (NULL == wiphy->bands[i])
8084 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308085 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308086 __func__, i);
8087 continue;
8088 }
8089
8090 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8091 {
8092 struct ieee80211_supported_band *band = wiphy->bands[i];
8093
8094 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8095 {
8096 // Enable social channels for P2P
8097 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8098 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8099 else
8100 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8101 continue;
8102 }
8103 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8104 {
8105 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8106 continue;
8107 }
8108 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008109 }
8110 /*Initialise the supported cipher suite details*/
8111 wiphy->cipher_suites = hdd_cipher_suites;
8112 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8113
8114 /*signal strength in mBm (100*dBm) */
8115 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8116
8117#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308118 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008119#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008120
Sunil Duttc69bccb2014-05-26 21:30:20 +05308121 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8122 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008123 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8124 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8125
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308126 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
8127
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308128 EXIT();
8129 return 0;
8130}
8131
8132/* In this function we are registering wiphy. */
8133int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8134{
8135 ENTER();
8136 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008137 if (0 > wiphy_register(wiphy))
8138 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308139 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008140 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8141 return -EIO;
8142 }
8143
8144 EXIT();
8145 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308146}
Jeff Johnson295189b2012-06-20 16:38:30 -07008147
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308148/* In this function we are updating channel list when,
8149 regulatory domain is FCC and country code is US.
8150 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8151 As per FCC smart phone is not a indoor device.
8152 GO should not opeate on indoor channels */
8153void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8154{
8155 int j;
8156 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8157 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8158 //Default counrtycode from NV at the time of wiphy initialization.
8159 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8160 &defaultCountryCode[0]))
8161 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008162 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308163 }
8164 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8165 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308166 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8167 {
8168 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8169 return;
8170 }
8171 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8172 {
8173 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8174 // Mark UNII -1 band channel as passive
8175 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8176 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8177 }
8178 }
8179}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308180/* This function registers for all frame which supplicant is interested in */
8181void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008182{
Jeff Johnson295189b2012-06-20 16:38:30 -07008183 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8184 /* Register for all P2P action, public action etc frames */
8185 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008186 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308187 /* Register frame indication call back */
8188 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008189 /* Right now we are registering these frame when driver is getting
8190 initialized. Once we will move to 2.6.37 kernel, in which we have
8191 frame register ops, we will move this code as a part of that */
8192 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308193 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008194 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8195
8196 /* GAS Initial Response */
8197 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8198 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308199
Jeff Johnson295189b2012-06-20 16:38:30 -07008200 /* GAS Comeback Request */
8201 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8202 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8203
8204 /* GAS Comeback Response */
8205 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8206 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8207
8208 /* P2P Public Action */
8209 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308210 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008211 P2P_PUBLIC_ACTION_FRAME_SIZE );
8212
8213 /* P2P Action */
8214 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8215 (v_U8_t*)P2P_ACTION_FRAME,
8216 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008217
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308218 /* WNM BSS Transition Request frame */
8219 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8220 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8221 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008222
8223 /* WNM-Notification */
8224 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8225 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8226 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008227}
8228
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308229void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008230{
Jeff Johnson295189b2012-06-20 16:38:30 -07008231 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8232 /* Register for all P2P action, public action etc frames */
8233 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8234
Jeff Johnsone7245742012-09-05 17:12:55 -07008235 ENTER();
8236
Jeff Johnson295189b2012-06-20 16:38:30 -07008237 /* Right now we are registering these frame when driver is getting
8238 initialized. Once we will move to 2.6.37 kernel, in which we have
8239 frame register ops, we will move this code as a part of that */
8240 /* GAS Initial Request */
8241
8242 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8243 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8244
8245 /* GAS Initial Response */
8246 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8247 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308248
Jeff Johnson295189b2012-06-20 16:38:30 -07008249 /* GAS Comeback Request */
8250 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8251 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8252
8253 /* GAS Comeback Response */
8254 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8255 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8256
8257 /* P2P Public Action */
8258 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308259 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008260 P2P_PUBLIC_ACTION_FRAME_SIZE );
8261
8262 /* P2P Action */
8263 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8264 (v_U8_t*)P2P_ACTION_FRAME,
8265 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008266 /* WNM-Notification */
8267 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8268 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8269 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008270}
8271
8272#ifdef FEATURE_WLAN_WAPI
8273void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308274 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008275{
8276 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8277 tCsrRoamSetKey setKey;
8278 v_BOOL_t isConnected = TRUE;
8279 int status = 0;
8280 v_U32_t roamId= 0xFF;
8281 tANI_U8 *pKeyPtr = NULL;
8282 int n = 0;
8283
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308284 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8285 __func__, hdd_device_modetoString(pAdapter->device_mode),
8286 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008287
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308288 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008289 setKey.keyId = key_index; // Store Key ID
8290 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8291 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8292 setKey.paeRole = 0 ; // the PAE role
8293 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8294 {
8295 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8296 }
8297 else
8298 {
8299 isConnected = hdd_connIsConnected(pHddStaCtx);
8300 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8301 }
8302 setKey.keyLength = key_Len;
8303 pKeyPtr = setKey.Key;
8304 memcpy( pKeyPtr, key, key_Len);
8305
Arif Hussain6d2a3322013-11-17 19:50:10 -08008306 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008307 __func__, key_Len);
8308 for (n = 0 ; n < key_Len; n++)
8309 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8310 __func__,n,setKey.Key[n]);
8311
8312 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8313 if ( isConnected )
8314 {
8315 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8316 pAdapter->sessionId, &setKey, &roamId );
8317 }
8318 if ( status != 0 )
8319 {
8320 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8321 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8322 __LINE__, status );
8323 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8324 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308325 /* Need to clear any trace of key value in the memory.
8326 * Thus zero out the memory even though it is local
8327 * variable.
8328 */
8329 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008330}
8331#endif /* FEATURE_WLAN_WAPI*/
8332
8333#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308334int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008335 beacon_data_t **ppBeacon,
8336 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008337#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308338int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008339 beacon_data_t **ppBeacon,
8340 struct cfg80211_beacon_data *params,
8341 int dtim_period)
8342#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308343{
Jeff Johnson295189b2012-06-20 16:38:30 -07008344 int size;
8345 beacon_data_t *beacon = NULL;
8346 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05308347 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
8348 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07008349
Jeff Johnsone7245742012-09-05 17:12:55 -07008350 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008351 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308352 {
8353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8354 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008355 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308356 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008357
8358 old = pAdapter->sessionCtx.ap.beacon;
8359
8360 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308361 {
8362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8363 FL("session(%d) old and new heads points to NULL"),
8364 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008365 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308366 }
8367
8368 if (params->tail && !params->tail_len)
8369 {
8370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8371 FL("tail_len is zero but tail is not NULL"));
8372 return -EINVAL;
8373 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008374
Jeff Johnson295189b2012-06-20 16:38:30 -07008375#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8376 /* Kernel 3.0 is not updating dtim_period for set beacon */
8377 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308378 {
8379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8380 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008381 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308382 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008383#endif
8384
Kapil Gupta137ef892016-12-13 19:38:00 +05308385 if (params->head)
8386 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008387 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308388 head = params->head;
8389 } else
8390 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008391 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308392 head = old->head;
8393 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008394
Kapil Gupta137ef892016-12-13 19:38:00 +05308395 if (params->tail || !old)
8396 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008397 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308398 tail = params->tail;
8399 } else
8400 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008401 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308402 tail = old->tail;
8403 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008404
Kapil Gupta137ef892016-12-13 19:38:00 +05308405 if (params->proberesp_ies || !old)
8406 {
8407 proberesp_ies_len = params->proberesp_ies_len;
8408 proberesp_ies = params->proberesp_ies;
8409 } else
8410 {
8411 proberesp_ies_len = old->proberesp_ies_len;
8412 proberesp_ies = old->proberesp_ies;
8413 }
8414
8415 if (params->assocresp_ies || !old)
8416 {
8417 assocresp_ies_len = params->assocresp_ies_len;
8418 assocresp_ies = params->assocresp_ies;
8419 } else
8420 {
8421 assocresp_ies_len = old->assocresp_ies_len;
8422 assocresp_ies = old->assocresp_ies;
8423 }
8424
8425 size = sizeof(beacon_data_t) + head_len + tail_len +
8426 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07008427
8428 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008429 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308430 {
8431 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8432 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008433 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308434 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008435
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008436#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05308437 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07008438 beacon->dtim_period = params->dtim_period;
8439 else
8440 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008441#else
Kapil Gupta137ef892016-12-13 19:38:00 +05308442 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008443 beacon->dtim_period = dtim_period;
8444 else
8445 beacon->dtim_period = old->dtim_period;
8446#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308447
Jeff Johnson295189b2012-06-20 16:38:30 -07008448 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8449 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308450 beacon->proberesp_ies = beacon->tail + tail_len;
8451 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
8452
Jeff Johnson295189b2012-06-20 16:38:30 -07008453 beacon->head_len = head_len;
8454 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308455 beacon->proberesp_ies_len = proberesp_ies_len;
8456 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07008457
c_manjee527ecac2017-01-25 12:25:27 +05308458 if (head && head_len)
8459 memcpy(beacon->head, head, head_len);
8460 if (tail && tail_len)
8461 memcpy(beacon->tail, tail, tail_len);
8462 if (proberesp_ies && proberesp_ies_len)
8463 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
8464 if (assocresp_ies && assocresp_ies_len)
8465 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008466
8467 *ppBeacon = beacon;
8468
8469 kfree(old);
8470
8471 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008472}
Jeff Johnson295189b2012-06-20 16:38:30 -07008473
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308474v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
8475#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
8476 const v_U8_t *pIes,
8477#else
8478 v_U8_t *pIes,
8479#endif
8480 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008481{
8482 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308483 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07008484 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308485
Jeff Johnson295189b2012-06-20 16:38:30 -07008486 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308487 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008488 elem_id = ptr[0];
8489 elem_len = ptr[1];
8490 left -= 2;
8491 if(elem_len > left)
8492 {
8493 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008494 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008495 eid,elem_len,left);
8496 return NULL;
8497 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308498 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008499 {
8500 return ptr;
8501 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308502
Jeff Johnson295189b2012-06-20 16:38:30 -07008503 left -= elem_len;
8504 ptr += (elem_len + 2);
8505 }
8506 return NULL;
8507}
8508
Jeff Johnson295189b2012-06-20 16:38:30 -07008509/* Check if rate is 11g rate or not */
8510static int wlan_hdd_rate_is_11g(u8 rate)
8511{
Sanjay Devnani28322e22013-06-21 16:13:40 -07008512 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008513 u8 i;
8514 for (i = 0; i < 8; i++)
8515 {
8516 if(rate == gRateArray[i])
8517 return TRUE;
8518 }
8519 return FALSE;
8520}
8521
8522/* Check for 11g rate and set proper 11g only mode */
8523static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
8524 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
8525{
8526 u8 i, num_rates = pIe[0];
8527
8528 pIe += 1;
8529 for ( i = 0; i < num_rates; i++)
8530 {
8531 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
8532 {
8533 /* If rate set have 11g rate than change the mode to 11G */
8534 *pSapHw_mode = eSAP_DOT11_MODE_11g;
8535 if (pIe[i] & BASIC_RATE_MASK)
8536 {
8537 /* If we have 11g rate as basic rate, it means mode
8538 is 11g only mode.
8539 */
8540 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
8541 *pCheckRatesfor11g = FALSE;
8542 }
8543 }
8544 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
8545 {
8546 *require_ht = TRUE;
8547 }
8548 }
8549 return;
8550}
8551
8552static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
8553{
8554 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8555 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8556 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8557 u8 checkRatesfor11g = TRUE;
8558 u8 require_ht = FALSE;
8559 u8 *pIe=NULL;
8560
8561 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
8562
8563 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
8564 pBeacon->head_len, WLAN_EID_SUPP_RATES);
8565 if (pIe != NULL)
8566 {
8567 pIe += 1;
8568 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8569 &pConfig->SapHw_mode);
8570 }
8571
8572 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8573 WLAN_EID_EXT_SUPP_RATES);
8574 if (pIe != NULL)
8575 {
8576
8577 pIe += 1;
8578 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8579 &pConfig->SapHw_mode);
8580 }
8581
8582 if( pConfig->channel > 14 )
8583 {
8584 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
8585 }
8586
8587 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8588 WLAN_EID_HT_CAPABILITY);
8589
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308590 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008591 {
8592 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
8593 if(require_ht)
8594 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
8595 }
8596}
8597
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308598static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
8599 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
8600{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008601 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308602 v_U8_t *pIe = NULL;
8603 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8604
8605 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
8606 pBeacon->tail, pBeacon->tail_len);
8607
8608 if (pIe)
8609 {
8610 ielen = pIe[1] + 2;
8611 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8612 {
8613 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
8614 }
8615 else
8616 {
8617 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
8618 return -EINVAL;
8619 }
8620 *total_ielen += ielen;
8621 }
8622 return 0;
8623}
8624
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008625static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
8626 v_U8_t *genie, v_U8_t *total_ielen)
8627{
8628 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8629 int left = pBeacon->tail_len;
8630 v_U8_t *ptr = pBeacon->tail;
8631 v_U8_t elem_id, elem_len;
8632 v_U16_t ielen = 0;
8633
8634 if ( NULL == ptr || 0 == left )
8635 return;
8636
8637 while (left >= 2)
8638 {
8639 elem_id = ptr[0];
8640 elem_len = ptr[1];
8641 left -= 2;
8642 if (elem_len > left)
8643 {
8644 hddLog( VOS_TRACE_LEVEL_ERROR,
8645 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
8646 elem_id, elem_len, left);
8647 return;
8648 }
8649 if (IE_EID_VENDOR == elem_id)
8650 {
8651 /* skipping the VSIE's which we don't want to include or
8652 * it will be included by existing code
8653 */
8654 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
8655#ifdef WLAN_FEATURE_WFD
8656 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
8657#endif
8658 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8659 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8660 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
8661 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8662 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
8663 {
8664 ielen = ptr[1] + 2;
8665 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8666 {
8667 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
8668 *total_ielen += ielen;
8669 }
8670 else
8671 {
8672 hddLog( VOS_TRACE_LEVEL_ERROR,
8673 "IE Length is too big "
8674 "IEs eid=%d elem_len=%d total_ie_lent=%d",
8675 elem_id, elem_len, *total_ielen);
8676 }
8677 }
8678 }
8679
8680 left -= elem_len;
8681 ptr += (elem_len + 2);
8682 }
8683 return;
8684}
8685
Kapil Gupta137ef892016-12-13 19:38:00 +05308686int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008687{
8688 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308689 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008690 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07008691 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05308692 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008693
8694 genie = vos_mem_malloc(MAX_GENIE_LEN);
8695
8696 if(genie == NULL) {
8697
8698 return -ENOMEM;
8699 }
8700
Kapil Gupta137ef892016-12-13 19:38:00 +05308701 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308702 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8703 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008704 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308705 hddLog(LOGE,
8706 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308707 ret = -EINVAL;
8708 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008709 }
8710
8711#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308712 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8713 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
8714 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308715 hddLog(LOGE,
8716 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308717 ret = -EINVAL;
8718 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008719 }
8720#endif
8721
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308722 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8723 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008724 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308725 hddLog(LOGE,
8726 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308727 ret = -EINVAL;
8728 goto done;
8729 }
8730
8731 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
8732 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008733 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07008734 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008735
8736 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8737 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
8738 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
8739 {
8740 hddLog(LOGE,
8741 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008742 ret = -EINVAL;
8743 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008744 }
8745
8746 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8747 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
8748 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8749 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8750 ==eHAL_STATUS_FAILURE)
8751 {
8752 hddLog(LOGE,
8753 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008754 ret = -EINVAL;
8755 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008756 }
8757
8758 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05308759 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008760 {
Kapil Gupta137ef892016-12-13 19:38:00 +05308761 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07008762 u8 probe_rsp_ie_len[3] = {0};
8763 u8 counter = 0;
8764 /* Check Probe Resp Length if it is greater then 255 then Store
8765 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
8766 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
8767 Store More then 255 bytes into One Variable.
8768 */
8769 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
8770 {
8771 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
8772 {
8773 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
8774 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
8775 }
8776 else
8777 {
8778 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
8779 rem_probe_resp_ie_len = 0;
8780 }
8781 }
8782
8783 rem_probe_resp_ie_len = 0;
8784
8785 if (probe_rsp_ie_len[0] > 0)
8786 {
8787 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8788 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05308789 (tANI_U8*)&pBeacon->
8790 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07008791 probe_rsp_ie_len[0], NULL,
8792 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8793 {
8794 hddLog(LOGE,
8795 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008796 ret = -EINVAL;
8797 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008798 }
8799 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
8800 }
8801
8802 if (probe_rsp_ie_len[1] > 0)
8803 {
8804 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8805 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05308806 (tANI_U8*)&pBeacon->
8807 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07008808 probe_rsp_ie_len[1], NULL,
8809 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8810 {
8811 hddLog(LOGE,
8812 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008813 ret = -EINVAL;
8814 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008815 }
8816 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
8817 }
8818
8819 if (probe_rsp_ie_len[2] > 0)
8820 {
8821 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8822 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05308823 (tANI_U8*)&pBeacon->
8824 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07008825 probe_rsp_ie_len[2], NULL,
8826 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8827 {
8828 hddLog(LOGE,
8829 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008830 ret = -EINVAL;
8831 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008832 }
8833 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
8834 }
8835
8836 if (probe_rsp_ie_len[1] == 0 )
8837 {
8838 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8839 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8840 eANI_BOOLEAN_FALSE) )
8841 {
8842 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008843 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008844 }
8845 }
8846
8847 if (probe_rsp_ie_len[2] == 0 )
8848 {
8849 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8850 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8851 eANI_BOOLEAN_FALSE) )
8852 {
8853 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008854 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008855 }
8856 }
8857
8858 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8859 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
8860 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8861 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8862 == eHAL_STATUS_FAILURE)
8863 {
8864 hddLog(LOGE,
8865 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008866 ret = -EINVAL;
8867 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008868 }
8869 }
8870 else
8871 {
8872 // Reset WNI_CFG_PROBE_RSP Flags
8873 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
8874
8875 hddLog(VOS_TRACE_LEVEL_INFO,
8876 "%s: No Probe Response IE received in set beacon",
8877 __func__);
8878 }
8879
8880 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05308881 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008882 {
8883 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05308884 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
8885 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07008886 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8887 {
8888 hddLog(LOGE,
8889 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008890 ret = -EINVAL;
8891 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008892 }
8893
8894 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8895 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
8896 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8897 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8898 == eHAL_STATUS_FAILURE)
8899 {
8900 hddLog(LOGE,
8901 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008902 ret = -EINVAL;
8903 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008904 }
8905 }
8906 else
8907 {
8908 hddLog(VOS_TRACE_LEVEL_INFO,
8909 "%s: No Assoc Response IE received in set beacon",
8910 __func__);
8911
8912 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8913 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8914 eANI_BOOLEAN_FALSE) )
8915 {
8916 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008917 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008918 }
8919 }
8920
Jeff Johnsone7245742012-09-05 17:12:55 -07008921done:
Jeff Johnson295189b2012-06-20 16:38:30 -07008922 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308923 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008924}
Jeff Johnson295189b2012-06-20 16:38:30 -07008925
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308926/*
Jeff Johnson295189b2012-06-20 16:38:30 -07008927 * FUNCTION: wlan_hdd_validate_operation_channel
8928 * called by wlan_hdd_cfg80211_start_bss() and
8929 * wlan_hdd_cfg80211_set_channel()
8930 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308931 * channel list.
8932 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07008933VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008934{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308935
Jeff Johnson295189b2012-06-20 16:38:30 -07008936 v_U32_t num_ch = 0;
8937 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8938 u32 indx = 0;
8939 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308940 v_U8_t fValidChannel = FALSE, count = 0;
8941 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308942
Jeff Johnson295189b2012-06-20 16:38:30 -07008943 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8944
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308945 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008946 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308947 /* Validate the channel */
8948 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008949 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308950 if ( channel == rfChannels[count].channelNum )
8951 {
8952 fValidChannel = TRUE;
8953 break;
8954 }
8955 }
8956 if (fValidChannel != TRUE)
8957 {
8958 hddLog(VOS_TRACE_LEVEL_ERROR,
8959 "%s: Invalid Channel [%d]", __func__, channel);
8960 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008961 }
8962 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308963 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008964 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308965 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8966 valid_ch, &num_ch))
8967 {
8968 hddLog(VOS_TRACE_LEVEL_ERROR,
8969 "%s: failed to get valid channel list", __func__);
8970 return VOS_STATUS_E_FAILURE;
8971 }
8972 for (indx = 0; indx < num_ch; indx++)
8973 {
8974 if (channel == valid_ch[indx])
8975 {
8976 break;
8977 }
8978 }
8979
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308980 if (indx >= num_ch)
8981 {
8982 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8983 {
8984 eCsrBand band;
8985 unsigned int freq;
8986
8987 sme_GetFreqBand(hHal, &band);
8988
8989 if (eCSR_BAND_5G == band)
8990 {
8991#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8992 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8993 {
8994 freq = ieee80211_channel_to_frequency(channel,
8995 IEEE80211_BAND_2GHZ);
8996 }
8997 else
8998 {
8999 freq = ieee80211_channel_to_frequency(channel,
9000 IEEE80211_BAND_5GHZ);
9001 }
9002#else
9003 freq = ieee80211_channel_to_frequency(channel);
9004#endif
9005 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
9006 return VOS_STATUS_SUCCESS;
9007 }
9008 }
9009
9010 hddLog(VOS_TRACE_LEVEL_ERROR,
9011 "%s: Invalid Channel [%d]", __func__, channel);
9012 return VOS_STATUS_E_FAILURE;
9013 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009014 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309015
Jeff Johnson295189b2012-06-20 16:38:30 -07009016 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309017
Jeff Johnson295189b2012-06-20 16:38:30 -07009018}
9019
Viral Modi3a32cc52013-02-08 11:14:52 -08009020/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309021 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009022 * This function is used to set the channel number
9023 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309024static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009025 struct ieee80211_channel *chan,
9026 enum nl80211_channel_type channel_type
9027 )
9028{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309029 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009030 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009031 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009032 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309033 hdd_context_t *pHddCtx;
9034 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009035
9036 ENTER();
9037
9038 if( NULL == dev )
9039 {
9040 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009041 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009042 return -ENODEV;
9043 }
9044 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309045
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309046 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9047 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
9048 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08009049 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309050 "%s: device_mode = %s (%d) freq = %d", __func__,
9051 hdd_device_modetoString(pAdapter->device_mode),
9052 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309053
9054 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9055 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309056 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08009057 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309058 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009059 }
9060
9061 /*
9062 * Do freq to chan conversion
9063 * TODO: for 11a
9064 */
9065
9066 channel = ieee80211_frequency_to_channel(freq);
9067
9068 /* Check freq range */
9069 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9070 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9071 {
9072 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009073 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009074 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9075 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9076 return -EINVAL;
9077 }
9078
9079 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9080
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309081 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9082 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009083 {
9084 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
9085 {
9086 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009087 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009088 return -EINVAL;
9089 }
9090 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9091 "%s: set channel to [%d] for device mode =%d",
9092 __func__, channel,pAdapter->device_mode);
9093 }
9094 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009095 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009096 )
9097 {
9098 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9099 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9100 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9101
9102 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9103 {
9104 /* Link is up then return cant set channel*/
9105 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009106 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009107 return -EINVAL;
9108 }
9109
9110 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9111 pHddStaCtx->conn_info.operationChannel = channel;
9112 pRoamProfile->ChannelInfo.ChannelList =
9113 &pHddStaCtx->conn_info.operationChannel;
9114 }
9115 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009116 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009117 )
9118 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309119 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9120 {
9121 if(VOS_STATUS_SUCCESS !=
9122 wlan_hdd_validate_operation_channel(pAdapter,channel))
9123 {
9124 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009125 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309126 return -EINVAL;
9127 }
9128 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9129 }
9130 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009131 {
9132 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9133
9134 /* If auto channel selection is configured as enable/ 1 then ignore
9135 channel set by supplicant
9136 */
9137 if ( cfg_param->apAutoChannelSelection )
9138 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309139 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9140 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009141 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309142 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9143 __func__, hdd_device_modetoString(pAdapter->device_mode),
9144 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009145 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309146 else
9147 {
9148 if(VOS_STATUS_SUCCESS !=
9149 wlan_hdd_validate_operation_channel(pAdapter,channel))
9150 {
9151 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009152 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309153 return -EINVAL;
9154 }
9155 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9156 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009157 }
9158 }
9159 else
9160 {
9161 hddLog(VOS_TRACE_LEVEL_FATAL,
9162 "%s: Invalid device mode failed to set valid channel", __func__);
9163 return -EINVAL;
9164 }
9165 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309166 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009167}
9168
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309169static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9170 struct net_device *dev,
9171 struct ieee80211_channel *chan,
9172 enum nl80211_channel_type channel_type
9173 )
9174{
9175 int ret;
9176
9177 vos_ssr_protect(__func__);
9178 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9179 vos_ssr_unprotect(__func__);
9180
9181 return ret;
9182}
9183
Anurag Chouhan83026002016-12-13 22:46:21 +05309184#ifdef DHCP_SERVER_OFFLOAD
9185void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
9186 VOS_STATUS status)
9187{
9188 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
9189
9190 ENTER();
9191
9192 if (NULL == adapter)
9193 {
9194 hddLog(VOS_TRACE_LEVEL_ERROR,
9195 "%s: adapter is NULL",__func__);
9196 return;
9197 }
9198
9199 adapter->dhcp_status.dhcp_offload_status = status;
9200 vos_event_set(&adapter->dhcp_status.vos_event);
9201 return;
9202}
9203
9204/**
9205 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
9206 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309207 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +05309208 *
9209 * Return: None
9210 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309211VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
9212 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +05309213{
9214 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
9215 sir_dhcp_srv_offload_info dhcp_srv_info;
9216 tANI_U8 num_entries = 0;
9217 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
9218 tANI_U8 num;
9219 tANI_U32 temp;
9220 VOS_STATUS ret;
9221
9222 ENTER();
9223
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309224 if (!re_init) {
9225 ret = wlan_hdd_validate_context(hdd_ctx);
9226 if (0 != ret)
9227 return VOS_STATUS_E_INVAL;
9228 }
Anurag Chouhan83026002016-12-13 22:46:21 +05309229
9230 /* Prepare the request to send to SME */
9231 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
9232 if (NULL == dhcp_srv_info) {
9233 hddLog(VOS_TRACE_LEVEL_ERROR,
9234 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
9235 return VOS_STATUS_E_NOMEM;
9236 }
9237
9238 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
9239
9240 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
9241 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
9242 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
9243 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
9244 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
9245 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
9246
9247 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
9248 srv_ip,
9249 &num_entries,
Anurag Chouhanac145c22016-11-22 16:51:47 +05309250 IPADDR_NUM_ENTRIES, ".");
Anurag Chouhan83026002016-12-13 22:46:21 +05309251 if (num_entries != IPADDR_NUM_ENTRIES) {
9252 hddLog(VOS_TRACE_LEVEL_ERROR,
9253 "%s: incorrect IP address (%s) assigned for DHCP server!",
9254 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9255 vos_mem_free(dhcp_srv_info);
9256 return VOS_STATUS_E_FAILURE;
9257 }
9258
9259 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
9260 hddLog(VOS_TRACE_LEVEL_ERROR,
9261 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
9262 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9263 vos_mem_free(dhcp_srv_info);
9264 return VOS_STATUS_E_FAILURE;
9265 }
9266
9267 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
9268 hddLog(VOS_TRACE_LEVEL_ERROR,
9269 "%s: invalid IP address (%s)! The last field must be less than 100!",
9270 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9271 vos_mem_free(dhcp_srv_info);
9272 return VOS_STATUS_E_FAILURE;
9273 }
9274
9275 for (num = 0; num < num_entries; num++) {
9276 temp = srv_ip[num];
9277 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
9278 }
9279
9280 if (eHAL_STATUS_SUCCESS !=
9281 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
9282 hddLog(VOS_TRACE_LEVEL_ERROR,
9283 "%s: sme_set_dhcp_srv_offload fail!", __func__);
9284 vos_mem_free(dhcp_srv_info);
9285 return VOS_STATUS_E_FAILURE;
9286 }
9287
9288 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9289 "%s: enable DHCP Server offload successfully!", __func__);
9290
9291 vos_mem_free(dhcp_srv_info);
9292 return 0;
9293}
9294#endif /* DHCP_SERVER_OFFLOAD */
9295
Jeff Johnson295189b2012-06-20 16:38:30 -07009296#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9297static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9298 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009299#else
9300static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9301 struct cfg80211_beacon_data *params,
9302 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309303 enum nl80211_hidden_ssid hidden_ssid,
9304 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009305#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009306{
9307 tsap_Config_t *pConfig;
9308 beacon_data_t *pBeacon = NULL;
9309 struct ieee80211_mgmt *pMgmt_frame;
9310 v_U8_t *pIe=NULL;
9311 v_U16_t capab_info;
9312 eCsrAuthType RSNAuthType;
9313 eCsrEncryptionType RSNEncryptType;
9314 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309315 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009316 tpWLAN_SAPEventCB pSapEventCallback;
9317 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -07009318 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309319 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009320 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309321 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009322 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009323 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309324 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009325 v_BOOL_t MFPCapable = VOS_FALSE;
9326 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309327 v_BOOL_t sapEnable11AC =
9328 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +05309329 u_int16_t prev_rsn_length = 0;
9330
Jeff Johnson295189b2012-06-20 16:38:30 -07009331 ENTER();
9332
Nitesh Shah9b066282017-06-06 18:05:52 +05309333 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309334 iniConfig = pHddCtx->cfg_ini;
9335
Jeff Johnson295189b2012-06-20 16:38:30 -07009336 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9337
9338 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9339
9340 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9341
9342 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9343
9344 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9345
9346 //channel is already set in the set_channel Call back
9347 //pConfig->channel = pCommitConfig->channel;
9348
9349 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309350 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009351 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9352
9353 pConfig->dtim_period = pBeacon->dtim_period;
9354
Arif Hussain6d2a3322013-11-17 19:50:10 -08009355 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009356 pConfig->dtim_period);
9357
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009358 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009359 {
9360 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009361 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309362 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9363 {
9364 tANI_BOOLEAN restartNeeded;
9365 pConfig->ieee80211d = 1;
9366 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9367 sme_setRegInfo(hHal, pConfig->countryCode);
9368 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9369 }
9370 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009371 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009372 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009373 pConfig->ieee80211d = 1;
9374 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9375 sme_setRegInfo(hHal, pConfig->countryCode);
9376 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009377 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009378 else
9379 {
9380 pConfig->ieee80211d = 0;
9381 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309382 /*
9383 * If auto channel is configured i.e. channel is 0,
9384 * so skip channel validation.
9385 */
9386 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9387 {
9388 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9389 {
9390 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009391 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309392 return -EINVAL;
9393 }
9394 }
9395 else
9396 {
9397 if(1 != pHddCtx->is_dynamic_channel_range_set)
9398 {
9399 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9400 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9401 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9402 }
9403 pHddCtx->is_dynamic_channel_range_set = 0;
9404 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009405 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009406 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009407 {
9408 pConfig->ieee80211d = 0;
9409 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309410
9411#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9412 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9413 pConfig->authType = eSAP_OPEN_SYSTEM;
9414 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9415 pConfig->authType = eSAP_SHARED_KEY;
9416 else
9417 pConfig->authType = eSAP_AUTO_SWITCH;
9418#else
9419 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9420 pConfig->authType = eSAP_OPEN_SYSTEM;
9421 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9422 pConfig->authType = eSAP_SHARED_KEY;
9423 else
9424 pConfig->authType = eSAP_AUTO_SWITCH;
9425#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009426
9427 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309428
9429 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009430 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +05309431#ifdef SAP_AUTH_OFFLOAD
9432 /* In case of sap offload, hostapd.conf is configuted with open mode and
9433 * security is configured from ini file. Due to open mode in hostapd.conf
9434 * privacy bit is set to false which will result in not sending,
9435 * data packets as encrypted.
9436 * If enable_sap_auth_offload is enabled in ini and
9437 * sap_auth_offload_sec_type is type of WPA2-PSK,
9438 * driver will set privacy bit to 1.
9439 */
9440 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
9441 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
9442 pConfig->privacy = VOS_TRUE;
9443#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009444
9445 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9446
9447 /*Set wps station to configured*/
9448 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9449
9450 if(pIe)
9451 {
9452 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9453 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009454 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009455 return -EINVAL;
9456 }
9457 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
9458 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009459 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07009460 /* Check 15 bit of WPS IE as it contain information for wps state
9461 * WPS state
9462 */
9463 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
9464 {
9465 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
9466 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
9467 {
9468 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
9469 }
9470 }
9471 }
9472 else
9473 {
9474 pConfig->wps_state = SAP_WPS_DISABLED;
9475 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309476 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07009477
c_hpothufe599e92014-06-16 11:38:55 +05309478 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9479 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9480 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
9481 eCSR_ENCRYPT_TYPE_NONE;
9482
Jeff Johnson295189b2012-06-20 16:38:30 -07009483 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309484 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309485 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009486 WLAN_EID_RSN);
9487 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309488 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009489 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +05309490 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
9491 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
9492 pConfig->RSNWPAReqIELength);
9493 else
9494 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
9495 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309496 /* The actual processing may eventually be more extensive than
9497 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07009498 * by the app.
9499 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309500 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009501 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9502 &RSNEncryptType,
9503 &mcRSNEncryptType,
9504 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009505 &MFPCapable,
9506 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +05309507 pConfig->RSNWPAReqIE[1]+2,
9508 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009509
9510 if( VOS_STATUS_SUCCESS == status )
9511 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309512 /* Now copy over all the security attributes you have
9513 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009514 * */
9515 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9516 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9517 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9518 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309519 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009520 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009521 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9522 }
9523 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309524
Jeff Johnson295189b2012-06-20 16:38:30 -07009525 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9526 pBeacon->tail, pBeacon->tail_len);
9527
9528 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
9529 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309530 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07009531 {
9532 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +05309533 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -07009534 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +05309535 if (pConfig->RSNWPAReqIELength <=
9536 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
9537 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
9538 pIe[1] + 2);
9539 else
9540 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
9541 pConfig->RSNWPAReqIELength);
9542
Jeff Johnson295189b2012-06-20 16:38:30 -07009543 }
9544 else
9545 {
9546 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +05309547 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
9548 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
9549 pConfig->RSNWPAReqIELength);
9550 else
9551 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
9552 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309553 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009554 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9555 &RSNEncryptType,
9556 &mcRSNEncryptType,
9557 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009558 &MFPCapable,
9559 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +05309560 pConfig->RSNWPAReqIE[1]+2,
9561 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009562
9563 if( VOS_STATUS_SUCCESS == status )
9564 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309565 /* Now copy over all the security attributes you have
9566 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009567 * */
9568 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9569 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9570 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9571 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309572 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009573 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009574 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9575 }
9576 }
9577 }
9578
Kapil Gupta137ef892016-12-13 19:38:00 +05309579 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -07009580 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
9581 return -EINVAL;
9582 }
9583
Jeff Johnson295189b2012-06-20 16:38:30 -07009584 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
9585
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009586#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009587 if (params->ssid != NULL)
9588 {
9589 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
9590 pConfig->SSIDinfo.ssid.length = params->ssid_len;
9591 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9592 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9593 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009594#else
9595 if (ssid != NULL)
9596 {
9597 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
9598 pConfig->SSIDinfo.ssid.length = ssid_len;
9599 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9600 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9601 }
9602#endif
9603
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309604 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07009605 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309606
Jeff Johnson295189b2012-06-20 16:38:30 -07009607 /* default value */
9608 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9609 pConfig->num_accept_mac = 0;
9610 pConfig->num_deny_mac = 0;
9611
9612 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9613 pBeacon->tail, pBeacon->tail_len);
9614
9615 /* pIe for black list is following form:
9616 type : 1 byte
9617 length : 1 byte
9618 OUI : 4 bytes
9619 acl type : 1 byte
9620 no of mac addr in black list: 1 byte
9621 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309622 */
9623 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009624 {
9625 pConfig->SapMacaddr_acl = pIe[6];
9626 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009627 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009628 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309629 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
9630 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009631 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9632 for (i = 0; i < pConfig->num_deny_mac; i++)
9633 {
9634 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9635 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309636 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009637 }
9638 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9639 pBeacon->tail, pBeacon->tail_len);
9640
9641 /* pIe for white list is following form:
9642 type : 1 byte
9643 length : 1 byte
9644 OUI : 4 bytes
9645 acl type : 1 byte
9646 no of mac addr in white list: 1 byte
9647 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309648 */
9649 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009650 {
9651 pConfig->SapMacaddr_acl = pIe[6];
9652 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009653 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009654 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309655 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
9656 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009657 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9658 for (i = 0; i < pConfig->num_accept_mac; i++)
9659 {
9660 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9661 acl_entry++;
9662 }
9663 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309664
Jeff Johnson295189b2012-06-20 16:38:30 -07009665 wlan_hdd_set_sapHwmode(pHostapdAdapter);
9666
Jeff Johnsone7245742012-09-05 17:12:55 -07009667#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009668 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309669 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
9670 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05309671 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
9672 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009673 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
9674 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309675 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
9676 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07009677 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309678 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07009679 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309680 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009681
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309682 /* If ACS disable and selected channel <= 14
9683 * OR
9684 * ACS enabled and ACS operating band is choosen as 2.4
9685 * AND
9686 * VHT in 2.4G Disabled
9687 * THEN
9688 * Fallback to 11N mode
9689 */
9690 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
9691 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05309692 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309693 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009694 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309695 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
9696 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009697 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
9698 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009699 }
9700#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309701
Jeff Johnson295189b2012-06-20 16:38:30 -07009702 // ht_capab is not what the name conveys,this is used for protection bitmap
9703 pConfig->ht_capab =
9704 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
9705
Kapil Gupta137ef892016-12-13 19:38:00 +05309706 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07009707 {
9708 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9709 return -EINVAL;
9710 }
9711
9712 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309713 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07009714 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
9715 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309716 pConfig->obssProtEnabled =
9717 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07009718
Chet Lanctot8cecea22014-02-11 19:09:36 -08009719#ifdef WLAN_FEATURE_11W
9720 pConfig->mfpCapable = MFPCapable;
9721 pConfig->mfpRequired = MFPRequired;
9722 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
9723 pConfig->mfpCapable, pConfig->mfpRequired);
9724#endif
9725
Arif Hussain6d2a3322013-11-17 19:50:10 -08009726 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07009727 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009728 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
9729 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
9730 (int)pConfig->channel);
9731 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
9732 pConfig->SapHw_mode, pConfig->privacy,
9733 pConfig->authType);
9734 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
9735 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
9736 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
9737 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07009738
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309739 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009740 {
9741 //Bss already started. just return.
9742 //TODO Probably it should update some beacon params.
9743 hddLog( LOGE, "Bss Already started...Ignore the request");
9744 EXIT();
9745 return 0;
9746 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309747
Agarwal Ashish51325b52014-06-16 16:50:49 +05309748 if (vos_max_concurrent_connections_reached()) {
9749 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9750 return -EINVAL;
9751 }
9752
Jeff Johnson295189b2012-06-20 16:38:30 -07009753 pConfig->persona = pHostapdAdapter->device_mode;
9754
Peng Xu2446a892014-09-05 17:21:18 +05309755 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
9756 if ( NULL != psmeConfig)
9757 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309758 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05309759 sme_GetConfigParam(hHal, psmeConfig);
9760 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309761#ifdef WLAN_FEATURE_AP_HT40_24G
9762 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
9763 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
9764 && pHddCtx->cfg_ini->apHT40_24GEnabled)
9765 {
9766 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
9767 sme_UpdateConfig (hHal, psmeConfig);
9768 }
9769#endif
Peng Xu2446a892014-09-05 17:21:18 +05309770 vos_mem_free(psmeConfig);
9771 }
Peng Xuafc34e32014-09-25 13:23:55 +05309772 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05309773
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309774 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
9775
Jeff Johnson295189b2012-06-20 16:38:30 -07009776 pSapEventCallback = hdd_hostapd_SAPEventCB;
9777 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
9778 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
9779 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009780 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309781 ret = -EINVAL;
9782 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07009783 }
9784
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309785 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07009786 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
9787
9788 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309789
Jeff Johnson295189b2012-06-20 16:38:30 -07009790 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309791 {
9792 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009793 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07009794 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009795 VOS_ASSERT(0);
9796 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309797
Jeff Johnson295189b2012-06-20 16:38:30 -07009798 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +05309799 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
9800 VOS_STATUS_SUCCESS)
9801 {
9802 hddLog(LOGE,FL("Fail to get Softap sessionID"));
9803 VOS_ASSERT(0);
9804 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +05309805 /* Initialize WMM configuation */
9806 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309807 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009808
Anurag Chouhan83026002016-12-13 22:46:21 +05309809#ifdef DHCP_SERVER_OFFLOAD
9810 /* set dhcp server offload */
9811 if (iniConfig->enable_dhcp_srv_offload &&
9812 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309813 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309814 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +05309815 if (!VOS_IS_STATUS_SUCCESS(status))
9816 {
9817 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9818 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309819 vos_event_reset(&pHostapdState->vosEvent);
9820 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
9821 status = vos_wait_single_event(&pHostapdState->vosEvent,
9822 10000);
9823 if (!VOS_IS_STATUS_SUCCESS(status)) {
9824 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309825 ret = -EINVAL;
9826 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309827 }
9828 }
Anurag Chouhan83026002016-12-13 22:46:21 +05309829 }
Anurag Chouhan83026002016-12-13 22:46:21 +05309830 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
9831 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
9832 {
9833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9834 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
9835 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309836 vos_event_reset(&pHostapdState->vosEvent);
9837 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
9838 status = vos_wait_single_event(&pHostapdState->vosEvent,
9839 10000);
9840 if (!VOS_IS_STATUS_SUCCESS(status)) {
9841 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309842 ret = -EINVAL;
9843 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309844 }
9845 }
Anurag Chouhan83026002016-12-13 22:46:21 +05309846 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +05309847#ifdef MDNS_OFFLOAD
9848 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309849 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +05309850 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
9851 if (VOS_IS_STATUS_SUCCESS(status))
9852 {
9853 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9854 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309855 vos_event_reset(&pHostapdState->vosEvent);
9856 if (VOS_STATUS_SUCCESS ==
9857 WLANSAP_StopBss(pHddCtx->pvosContext)) {
9858 status = vos_wait_single_event(&pHostapdState->vosEvent,
9859 10000);
9860 if (!VOS_IS_STATUS_SUCCESS(status)) {
9861 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309862 ret = -EINVAL;
9863 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309864 }
9865 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +05309866 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +05309867 status = vos_wait_single_event(&pHostapdAdapter->
9868 mdns_status.vos_event, 2000);
9869 if (!VOS_IS_STATUS_SUCCESS(status) ||
9870 pHostapdAdapter->mdns_status.mdns_enable_status ||
9871 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
9872 pHostapdAdapter->mdns_status.mdns_resp_status)
9873 {
9874 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9875 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
9876 pHostapdAdapter->mdns_status.mdns_enable_status,
9877 pHostapdAdapter->mdns_status.mdns_fqdn_status,
9878 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309879 vos_event_reset(&pHostapdState->vosEvent);
9880 if (VOS_STATUS_SUCCESS ==
9881 WLANSAP_StopBss(pHddCtx->pvosContext)) {
9882 status = vos_wait_single_event(&pHostapdState->vosEvent,
9883 10000);
9884 if (!VOS_IS_STATUS_SUCCESS(status)) {
9885 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309886 ret = -EINVAL;
9887 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309888 }
9889 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +05309890 }
9891 }
9892#endif /* MDNS_OFFLOAD */
9893 } else {
9894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9895 ("DHCP Disabled ini %d, FW %d"),
9896 iniConfig->enable_dhcp_srv_offload,
9897 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +05309898 }
9899#endif /* DHCP_SERVER_OFFLOAD */
9900
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009901#ifdef WLAN_FEATURE_P2P_DEBUG
9902 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
9903 {
9904 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
9905 {
9906 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9907 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009908 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009909 }
9910 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
9911 {
9912 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9913 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009914 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009915 }
9916 }
9917#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +05309918 /* Check and restart SAP if it is on Unsafe channel */
9919 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009920
Jeff Johnson295189b2012-06-20 16:38:30 -07009921 pHostapdState->bCommit = TRUE;
9922 EXIT();
9923
9924 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309925error:
9926 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
9927 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009928}
9929
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009930#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309931static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309932 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009933 struct beacon_parameters *params)
9934{
9935 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309936 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309937 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009938
9939 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309940
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309941 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9942 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
9943 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309944 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
9945 hdd_device_modetoString(pAdapter->device_mode),
9946 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009947
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309948 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9949 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309950 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009951 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309952 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009953 }
9954
Agarwal Ashish51325b52014-06-16 16:50:49 +05309955 if (vos_max_concurrent_connections_reached()) {
9956 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9957 return -EINVAL;
9958 }
9959
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309960 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009961 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009962 )
9963 {
9964 beacon_data_t *old,*new;
9965
9966 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309967
Jeff Johnson295189b2012-06-20 16:38:30 -07009968 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309969 {
9970 hddLog(VOS_TRACE_LEVEL_WARN,
9971 FL("already beacon info added to session(%d)"),
9972 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009973 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309974 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009975
9976 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9977
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309978 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07009979 {
9980 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009981 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009982 return -EINVAL;
9983 }
9984
9985 pAdapter->sessionCtx.ap.beacon = new;
9986
9987 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9988 }
9989
9990 EXIT();
9991 return status;
9992}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309993
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309994static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
9995 struct net_device *dev,
9996 struct beacon_parameters *params)
9997{
9998 int ret;
9999
10000 vos_ssr_protect(__func__);
10001 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
10002 vos_ssr_unprotect(__func__);
10003
10004 return ret;
10005}
10006
10007static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010008 struct net_device *dev,
10009 struct beacon_parameters *params)
10010{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010011 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010012 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10013 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010014 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010015
10016 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010017
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010018 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10019 TRACE_CODE_HDD_CFG80211_SET_BEACON,
10020 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
10021 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10022 __func__, hdd_device_modetoString(pAdapter->device_mode),
10023 pAdapter->device_mode);
10024
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010025 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10026 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010027 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010028 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010029 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010030 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010031
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010032 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010033 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010034 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010035 {
10036 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010037
Jeff Johnson295189b2012-06-20 16:38:30 -070010038 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010039
Jeff Johnson295189b2012-06-20 16:38:30 -070010040 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010041 {
10042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10043 FL("session(%d) old and new heads points to NULL"),
10044 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010045 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010046 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010047
10048 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10049
10050 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010051 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010052 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010053 return -EINVAL;
10054 }
10055
10056 pAdapter->sessionCtx.ap.beacon = new;
10057
10058 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10059 }
10060
10061 EXIT();
10062 return status;
10063}
10064
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010065static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
10066 struct net_device *dev,
10067 struct beacon_parameters *params)
10068{
10069 int ret;
10070
10071 vos_ssr_protect(__func__);
10072 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
10073 vos_ssr_unprotect(__func__);
10074
10075 return ret;
10076}
10077
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010078#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10079
10080#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010081static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010082 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010083#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010084static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010085 struct net_device *dev)
10086#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010087{
10088 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070010089 hdd_context_t *pHddCtx = NULL;
10090 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010091 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010092 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010093
10094 ENTER();
10095
10096 if (NULL == pAdapter)
10097 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010099 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010100 return -ENODEV;
10101 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010102
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010103 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10104 TRACE_CODE_HDD_CFG80211_STOP_AP,
10105 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010106 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10107 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010108 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010109 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010110 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070010111 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010112
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010113 pScanInfo = &pHddCtx->scan_info;
10114
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010115 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10116 __func__, hdd_device_modetoString(pAdapter->device_mode),
10117 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010118
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010119 ret = wlan_hdd_scan_abort(pAdapter);
10120
Girish Gowli4bf7a632014-06-12 13:42:11 +053010121 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070010122 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10124 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010125
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010126 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070010127 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010128 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10129 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080010130
Jeff Johnsone7245742012-09-05 17:12:55 -070010131 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010132 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070010133 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010134 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010135 }
10136
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010137 /* Delete all associated STAs before stopping AP/P2P GO */
10138 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053010139 hdd_hostapd_stop(dev);
10140
Jeff Johnson295189b2012-06-20 16:38:30 -070010141 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010142 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010143 )
10144 {
10145 beacon_data_t *old;
10146
10147 old = pAdapter->sessionCtx.ap.beacon;
10148
10149 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010150 {
10151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10152 FL("session(%d) beacon data points to NULL"),
10153 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010154 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010155 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010156
Jeff Johnson295189b2012-06-20 16:38:30 -070010157 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010158
10159 mutex_lock(&pHddCtx->sap_lock);
10160 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10161 {
Jeff Johnson4416a782013-03-25 14:17:50 -070010162 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010163 {
10164 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10165
10166 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10167
10168 if (!VOS_IS_STATUS_SUCCESS(status))
10169 {
10170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010171 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010172 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010173 }
10174 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010175 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010176 /* BSS stopped, clear the active sessions for this device mode */
10177 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010178 }
10179 mutex_unlock(&pHddCtx->sap_lock);
10180
10181 if(status != VOS_STATUS_SUCCESS)
10182 {
10183 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010184 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010185 return -EINVAL;
10186 }
10187
Jeff Johnson4416a782013-03-25 14:17:50 -070010188 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010189 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
10190 ==eHAL_STATUS_FAILURE)
10191 {
10192 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010193 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010194 }
10195
Jeff Johnson4416a782013-03-25 14:17:50 -070010196 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010197 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10198 eANI_BOOLEAN_FALSE) )
10199 {
10200 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010201 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010202 }
10203
10204 // Reset WNI_CFG_PROBE_RSP Flags
10205 wlan_hdd_reset_prob_rspies(pAdapter);
10206
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010207 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
10208
Jeff Johnson295189b2012-06-20 16:38:30 -070010209 pAdapter->sessionCtx.ap.beacon = NULL;
10210 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010211#ifdef WLAN_FEATURE_P2P_DEBUG
10212 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
10213 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
10214 {
10215 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
10216 "GO got removed");
10217 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
10218 }
10219#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010220 }
10221 EXIT();
10222 return status;
10223}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010224
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010225#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10226static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
10227 struct net_device *dev)
10228{
10229 int ret;
10230
10231 vos_ssr_protect(__func__);
10232 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
10233 vos_ssr_unprotect(__func__);
10234
10235 return ret;
10236}
10237#else
10238static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
10239 struct net_device *dev)
10240{
10241 int ret;
10242
10243 vos_ssr_protect(__func__);
10244 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
10245 vos_ssr_unprotect(__func__);
10246
10247 return ret;
10248}
10249#endif
10250
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010251#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
10252
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010253static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010254 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010255 struct cfg80211_ap_settings *params)
10256{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010257 hdd_adapter_t *pAdapter;
10258 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010259 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010260
10261 ENTER();
10262
Girish Gowlib143d7a2015-02-18 19:39:55 +053010263 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010264 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053010266 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010267 return -ENODEV;
10268 }
10269
10270 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10271 if (NULL == pAdapter)
10272 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010273 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010274 "%s: HDD adapter is Null", __func__);
10275 return -ENODEV;
10276 }
10277
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010278 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10279 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
10280 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010281 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
10282 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010284 "%s: HDD adapter magic is invalid", __func__);
10285 return -ENODEV;
10286 }
10287
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010288 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
10289
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010290 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010291 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010292 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010293 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010294 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010295 }
10296
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010297 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
10298 __func__, hdd_device_modetoString(pAdapter->device_mode),
10299 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010300
10301 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010302 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010303 )
10304 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010305 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010306
10307 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010308
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010309 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010310 {
10311 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10312 FL("already beacon info added to session(%d)"),
10313 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010314 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010315 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010316
Girish Gowlib143d7a2015-02-18 19:39:55 +053010317#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10318 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10319 &new,
10320 &params->beacon);
10321#else
10322 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10323 &new,
10324 &params->beacon,
10325 params->dtim_period);
10326#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010327
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010328 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010329 {
10330 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010331 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010332 return -EINVAL;
10333 }
10334 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010335#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010336 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10337#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10338 params->channel, params->channel_type);
10339#else
10340 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10341#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010342#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010343 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010344 params->ssid_len, params->hidden_ssid,
10345 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010346 }
10347
10348 EXIT();
10349 return status;
10350}
10351
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010352static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10353 struct net_device *dev,
10354 struct cfg80211_ap_settings *params)
10355{
10356 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010357
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010358 vos_ssr_protect(__func__);
10359 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10360 vos_ssr_unprotect(__func__);
10361
10362 return ret;
10363}
10364
10365static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010366 struct net_device *dev,
10367 struct cfg80211_beacon_data *params)
10368{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010369 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010370 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010371 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010372
10373 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010374
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010375 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10376 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10377 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010378 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010379 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010380
10381 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10382 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010383 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010384 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010385 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010386 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010387
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010388 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010389 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010390 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010391 {
10392 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010393
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010394 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010395
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010396 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010397 {
10398 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10399 FL("session(%d) beacon data points to NULL"),
10400 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010401 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010402 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010403
10404 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10405
10406 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010407 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010408 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010409 return -EINVAL;
10410 }
10411
10412 pAdapter->sessionCtx.ap.beacon = new;
10413
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010414 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10415 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010416 }
10417
10418 EXIT();
10419 return status;
10420}
10421
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010422static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10423 struct net_device *dev,
10424 struct cfg80211_beacon_data *params)
10425{
10426 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010427
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010428 vos_ssr_protect(__func__);
10429 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10430 vos_ssr_unprotect(__func__);
10431
10432 return ret;
10433}
10434
10435#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010436
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010437static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010438 struct net_device *dev,
10439 struct bss_parameters *params)
10440{
10441 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010442 hdd_context_t *pHddCtx;
10443 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010444
10445 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010446
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010447 if (NULL == pAdapter)
10448 {
10449 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10450 "%s: HDD adapter is Null", __func__);
10451 return -ENODEV;
10452 }
10453 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010454 ret = wlan_hdd_validate_context(pHddCtx);
10455 if (0 != ret)
10456 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010457 return ret;
10458 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010459 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10460 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
10461 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010462 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10463 __func__, hdd_device_modetoString(pAdapter->device_mode),
10464 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010465
10466 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010467 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010468 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010469 {
10470 /* ap_isolate == -1 means that in change bss, upper layer doesn't
10471 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010472 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070010473 {
10474 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010475 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010476 }
10477
10478 EXIT();
10479 return 0;
10480}
10481
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010482static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
10483 struct net_device *dev,
10484 struct bss_parameters *params)
10485{
10486 int ret;
10487
10488 vos_ssr_protect(__func__);
10489 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
10490 vos_ssr_unprotect(__func__);
10491
10492 return ret;
10493}
Kiet Lam10841362013-11-01 11:36:50 +053010494/* FUNCTION: wlan_hdd_change_country_code_cd
10495* to wait for contry code completion
10496*/
10497void* wlan_hdd_change_country_code_cb(void *pAdapter)
10498{
10499 hdd_adapter_t *call_back_pAdapter = pAdapter;
10500 complete(&call_back_pAdapter->change_country_code);
10501 return NULL;
10502}
10503
Jeff Johnson295189b2012-06-20 16:38:30 -070010504/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010505 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070010506 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
10507 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010508int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010509 struct net_device *ndev,
10510 enum nl80211_iftype type,
10511 u32 *flags,
10512 struct vif_params *params
10513 )
10514{
10515 struct wireless_dev *wdev;
10516 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010517 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070010518 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010519 tCsrRoamProfile *pRoamProfile = NULL;
10520 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010521 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010522 eMib_dot11DesiredBssType connectedBssType;
10523 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010524 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010525
10526 ENTER();
10527
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010528 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010529 {
10530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10531 "%s: Adapter context is null", __func__);
10532 return VOS_STATUS_E_FAILURE;
10533 }
10534
10535 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10536 if (!pHddCtx)
10537 {
10538 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10539 "%s: HDD context is null", __func__);
10540 return VOS_STATUS_E_FAILURE;
10541 }
10542
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010543 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10544 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
10545 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010546 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010547 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010548 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010549 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010550 }
10551
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010552 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10553 __func__, hdd_device_modetoString(pAdapter->device_mode),
10554 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010555
Agarwal Ashish51325b52014-06-16 16:50:49 +053010556 if (vos_max_concurrent_connections_reached()) {
10557 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10558 return -EINVAL;
10559 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010560 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070010561 wdev = ndev->ieee80211_ptr;
10562
10563#ifdef WLAN_BTAMP_FEATURE
10564 if((NL80211_IFTYPE_P2P_CLIENT == type)||
10565 (NL80211_IFTYPE_ADHOC == type)||
10566 (NL80211_IFTYPE_AP == type)||
10567 (NL80211_IFTYPE_P2P_GO == type))
10568 {
10569 pHddCtx->isAmpAllowed = VOS_FALSE;
10570 // stop AMP traffic
10571 status = WLANBAP_StopAmp();
10572 if(VOS_STATUS_SUCCESS != status )
10573 {
10574 pHddCtx->isAmpAllowed = VOS_TRUE;
10575 hddLog(VOS_TRACE_LEVEL_FATAL,
10576 "%s: Failed to stop AMP", __func__);
10577 return -EINVAL;
10578 }
10579 }
10580#endif //WLAN_BTAMP_FEATURE
10581 /* Reset the current device mode bit mask*/
10582 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10583
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053010584 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
10585 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
10586 (type == NL80211_IFTYPE_P2P_GO)))
10587 {
10588 /* Notify Mode change in case of concurrency.
10589 * Below function invokes TDLS teardown Functionality Since TDLS is
10590 * not Supported in case of concurrency i.e Once P2P session
10591 * is detected disable offchannel and teardown TDLS links
10592 */
10593 hddLog(LOG1,
10594 FL("Device mode = %d Interface type = %d"),
10595 pAdapter->device_mode, type);
10596 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
10597 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053010598
Jeff Johnson295189b2012-06-20 16:38:30 -070010599 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010600 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070010601 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010602 )
10603 {
10604 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010605 if (!pWextState)
10606 {
10607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10608 "%s: pWextState is null", __func__);
10609 return VOS_STATUS_E_FAILURE;
10610 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010611 pRoamProfile = &pWextState->roamProfile;
10612 LastBSSType = pRoamProfile->BSSType;
10613
10614 switch (type)
10615 {
10616 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010617 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010618 hddLog(VOS_TRACE_LEVEL_INFO,
10619 "%s: setting interface Type to INFRASTRUCTURE", __func__);
10620 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010621#ifdef WLAN_FEATURE_11AC
10622 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
10623 {
10624 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
10625 }
10626#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010627 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070010628 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010629 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010630 //Check for sub-string p2p to confirm its a p2p interface
10631 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010632 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053010633#ifdef FEATURE_WLAN_TDLS
10634 mutex_lock(&pHddCtx->tdls_lock);
10635 wlan_hdd_tdls_exit(pAdapter, TRUE);
10636 mutex_unlock(&pHddCtx->tdls_lock);
10637#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010638 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10639 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10640 }
10641 else
10642 {
10643 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010644 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010645 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010646 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053010647
Jeff Johnson295189b2012-06-20 16:38:30 -070010648 case NL80211_IFTYPE_ADHOC:
10649 hddLog(VOS_TRACE_LEVEL_INFO,
10650 "%s: setting interface Type to ADHOC", __func__);
10651 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
10652 pRoamProfile->phyMode =
10653 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070010654 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010655 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053010656 hdd_set_ibss_ops( pAdapter );
10657 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053010658
10659 status = hdd_sta_id_hash_attach(pAdapter);
10660 if (VOS_STATUS_SUCCESS != status) {
10661 hddLog(VOS_TRACE_LEVEL_ERROR,
10662 FL("Failed to initialize hash for IBSS"));
10663 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010664 break;
10665
10666 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010667 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010668 {
10669 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10670 "%s: setting interface Type to %s", __func__,
10671 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
10672
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010673 //Cancel any remain on channel for GO mode
10674 if (NL80211_IFTYPE_P2P_GO == type)
10675 {
10676 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
10677 }
Mohit Khanna0f232092012-09-11 14:46:08 -070010678 if (NL80211_IFTYPE_AP == type)
10679 {
10680 /* As Loading WLAN Driver one interface being created for p2p device
10681 * address. This will take one HW STA and the max number of clients
10682 * that can connect to softAP will be reduced by one. so while changing
10683 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
10684 * interface as it is not required in SoftAP mode.
10685 */
10686
10687 // Get P2P Adapter
10688 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
10689
10690 if (pP2pAdapter)
10691 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010692 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053010693 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070010694 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
10695 }
10696 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053010697 //Disable IMPS & BMPS for SAP/GO
10698 if(VOS_STATUS_E_FAILURE ==
10699 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
10700 {
10701 //Fail to Exit BMPS
10702 VOS_ASSERT(0);
10703 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053010704
10705 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
10706
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010707#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070010708
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010709 /* A Mutex Lock is introduced while changing the mode to
10710 * protect the concurrent access for the Adapters by TDLS
10711 * module.
10712 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010713 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010714#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010715 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053010716 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010717 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070010718 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10719 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010720#ifdef FEATURE_WLAN_TDLS
10721 mutex_unlock(&pHddCtx->tdls_lock);
10722#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010723 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
10724 (pConfig->apRandomBssidEnabled))
10725 {
10726 /* To meet Android requirements create a randomized
10727 MAC address of the form 02:1A:11:Fx:xx:xx */
10728 get_random_bytes(&ndev->dev_addr[3], 3);
10729 ndev->dev_addr[0] = 0x02;
10730 ndev->dev_addr[1] = 0x1A;
10731 ndev->dev_addr[2] = 0x11;
10732 ndev->dev_addr[3] |= 0xF0;
10733 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
10734 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080010735 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
10736 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010737 }
10738
Jeff Johnson295189b2012-06-20 16:38:30 -070010739 hdd_set_ap_ops( pAdapter->dev );
10740
Kiet Lam10841362013-11-01 11:36:50 +053010741 /* This is for only SAP mode where users can
10742 * control country through ini.
10743 * P2P GO follows station country code
10744 * acquired during the STA scanning. */
10745 if((NL80211_IFTYPE_AP == type) &&
10746 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
10747 {
10748 int status = 0;
10749 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
10750 "%s: setting country code from INI ", __func__);
10751 init_completion(&pAdapter->change_country_code);
10752 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
10753 (void *)(tSmeChangeCountryCallback)
10754 wlan_hdd_change_country_code_cb,
10755 pConfig->apCntryCode, pAdapter,
10756 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010757 eSIR_FALSE,
10758 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053010759 if (eHAL_STATUS_SUCCESS == status)
10760 {
10761 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010762 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053010763 &pAdapter->change_country_code,
10764 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010765 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053010766 {
10767 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010768 FL("SME Timed out while setting country code %ld"),
10769 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080010770
10771 if (pHddCtx->isLogpInProgress)
10772 {
10773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10774 "%s: LOGP in Progress. Ignore!!!", __func__);
10775 return -EAGAIN;
10776 }
Kiet Lam10841362013-11-01 11:36:50 +053010777 }
10778 }
10779 else
10780 {
10781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010782 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053010783 return -EINVAL;
10784 }
10785 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053010786 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070010787 if(status != VOS_STATUS_SUCCESS)
10788 {
10789 hddLog(VOS_TRACE_LEVEL_FATAL,
10790 "%s: Error initializing the ap mode", __func__);
10791 return -EINVAL;
10792 }
10793 hdd_set_conparam(1);
10794
Nirav Shah7e3c8132015-06-22 23:51:42 +053010795 status = hdd_sta_id_hash_attach(pAdapter);
10796 if (VOS_STATUS_SUCCESS != status)
10797 {
10798 hddLog(VOS_TRACE_LEVEL_ERROR,
10799 FL("Failed to initialize hash for AP"));
10800 return -EINVAL;
10801 }
10802
Jeff Johnson295189b2012-06-20 16:38:30 -070010803 /*interface type changed update in wiphy structure*/
10804 if(wdev)
10805 {
10806 wdev->iftype = type;
10807 pHddCtx->change_iface = type;
10808 }
10809 else
10810 {
10811 hddLog(VOS_TRACE_LEVEL_ERROR,
10812 "%s: ERROR !!!! Wireless dev is NULL", __func__);
10813 return -EINVAL;
10814 }
10815 goto done;
10816 }
10817
10818 default:
10819 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10820 __func__);
10821 return -EOPNOTSUPP;
10822 }
10823 }
10824 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010825 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010826 )
10827 {
10828 switch(type)
10829 {
10830 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010831 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010832 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053010833
10834 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010835#ifdef FEATURE_WLAN_TDLS
10836
10837 /* A Mutex Lock is introduced while changing the mode to
10838 * protect the concurrent access for the Adapters by TDLS
10839 * module.
10840 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010841 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010842#endif
c_hpothu002231a2015-02-05 14:58:51 +053010843 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010844 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010845 //Check for sub-string p2p to confirm its a p2p interface
10846 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010847 {
10848 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10849 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10850 }
10851 else
10852 {
10853 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010854 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010855 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053010856
10857 /* set con_mode to STA only when no SAP concurrency mode */
10858 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
10859 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070010860 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010861 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
10862 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010863#ifdef FEATURE_WLAN_TDLS
10864 mutex_unlock(&pHddCtx->tdls_lock);
10865#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053010866 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070010867 if( VOS_STATUS_SUCCESS != status )
10868 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070010869 /* In case of JB, for P2P-GO, only change interface will be called,
10870 * This is the right place to enable back bmps_imps()
10871 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010872 if (pHddCtx->hdd_wlan_suspended)
10873 {
10874 hdd_set_pwrparams(pHddCtx);
10875 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010876 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010877 goto done;
10878 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010879 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010880 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010881 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10882 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010883 goto done;
10884 default:
10885 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10886 __func__);
10887 return -EOPNOTSUPP;
10888
10889 }
10890
10891 }
10892 else
10893 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010894 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
10895 __func__, hdd_device_modetoString(pAdapter->device_mode),
10896 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010897 return -EOPNOTSUPP;
10898 }
10899
10900
10901 if(pRoamProfile)
10902 {
10903 if ( LastBSSType != pRoamProfile->BSSType )
10904 {
10905 /*interface type changed update in wiphy structure*/
10906 wdev->iftype = type;
10907
10908 /*the BSS mode changed, We need to issue disconnect
10909 if connected or in IBSS disconnect state*/
10910 if ( hdd_connGetConnectedBssType(
10911 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
10912 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
10913 {
10914 /*need to issue a disconnect to CSR.*/
10915 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10916 if( eHAL_STATUS_SUCCESS ==
10917 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10918 pAdapter->sessionId,
10919 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10920 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010921 ret = wait_for_completion_interruptible_timeout(
10922 &pAdapter->disconnect_comp_var,
10923 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10924 if (ret <= 0)
10925 {
10926 hddLog(VOS_TRACE_LEVEL_ERROR,
10927 FL("wait on disconnect_comp_var failed %ld"), ret);
10928 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010929 }
10930 }
10931 }
10932 }
10933
10934done:
10935 /*set bitmask based on updated value*/
10936 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070010937
10938 /* Only STA mode support TM now
10939 * all other mode, TM feature should be disabled */
10940 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
10941 (~VOS_STA & pHddCtx->concurrency_mode) )
10942 {
10943 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
10944 }
10945
Jeff Johnson295189b2012-06-20 16:38:30 -070010946#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010947 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010948 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070010949 {
10950 //we are ok to do AMP
10951 pHddCtx->isAmpAllowed = VOS_TRUE;
10952 }
10953#endif //WLAN_BTAMP_FEATURE
10954 EXIT();
10955 return 0;
10956}
10957
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010958/*
10959 * FUNCTION: wlan_hdd_cfg80211_change_iface
10960 * wrapper function to protect the actual implementation from SSR.
10961 */
10962int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
10963 struct net_device *ndev,
10964 enum nl80211_iftype type,
10965 u32 *flags,
10966 struct vif_params *params
10967 )
10968{
10969 int ret;
10970
10971 vos_ssr_protect(__func__);
10972 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
10973 vos_ssr_unprotect(__func__);
10974
10975 return ret;
10976}
10977
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010978#ifdef FEATURE_WLAN_TDLS
10979static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010980 struct net_device *dev,
10981#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10982 const u8 *mac,
10983#else
10984 u8 *mac,
10985#endif
10986 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010987{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010988 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010989 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010990 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010991 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010992 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010993 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010994
10995 ENTER();
10996
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010997 if (!dev) {
10998 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
10999 return -EINVAL;
11000 }
11001
11002 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11003 if (!pAdapter) {
11004 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
11005 return -EINVAL;
11006 }
11007
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011008 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011009 {
11010 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11011 "Invalid arguments");
11012 return -EINVAL;
11013 }
Hoonki Lee27511902013-03-14 18:19:06 -070011014
11015 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
11016 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
11017 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011018 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070011019 "%s: TDLS mode is disabled OR not enabled in FW."
11020 MAC_ADDRESS_STR " Request declined.",
11021 __func__, MAC_ADDR_ARRAY(mac));
11022 return -ENOTSUPP;
11023 }
11024
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011025 if (pHddCtx->isLogpInProgress)
11026 {
11027 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11028 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053011029 wlan_hdd_tdls_set_link_status(pAdapter,
11030 mac,
11031 eTDLS_LINK_IDLE,
11032 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011033 return -EBUSY;
11034 }
11035
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011036 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053011037 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011038
11039 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011041 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
11042 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011043 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011044 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011045 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011046
11047 /* in add station, we accept existing valid staId if there is */
11048 if ((0 == update) &&
11049 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
11050 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011051 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011053 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011054 " link_status %d. staId %d. add station ignored.",
11055 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011056 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011057 return 0;
11058 }
11059 /* in change station, we accept only when staId is valid */
11060 if ((1 == update) &&
11061 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
11062 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
11063 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011064 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011065 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011066 "%s: " MAC_ADDRESS_STR
11067 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011068 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
11069 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
11070 mutex_unlock(&pHddCtx->tdls_lock);
11071 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011072 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011073 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011074
11075 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053011076 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011077 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011078 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11079 "%s: " MAC_ADDRESS_STR
11080 " TDLS setup is ongoing. Request declined.",
11081 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070011082 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011083 }
11084
11085 /* first to check if we reached to maximum supported TDLS peer.
11086 TODO: for now, return -EPERM looks working fine,
11087 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011088 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
11089 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011090 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11092 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011093 " TDLS Max peer already connected. Request declined."
11094 " Num of peers (%d), Max allowed (%d).",
11095 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
11096 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011097 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011098 }
11099 else
11100 {
11101 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011102 mutex_lock(&pHddCtx->tdls_lock);
11103 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011104 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011105 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011106 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11108 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
11109 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011110 return -EPERM;
11111 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011112 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011113 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011114 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053011115 wlan_hdd_tdls_set_link_status(pAdapter,
11116 mac,
11117 eTDLS_LINK_CONNECTING,
11118 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011119
Jeff Johnsond75fe012013-04-06 10:53:06 -070011120 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011121 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011122 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011123 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011124 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011125 if(StaParams->htcap_present)
11126 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011128 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011129 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011130 "ht_capa->extended_capabilities: %0x",
11131 StaParams->HTCap.extendedHtCapInfo);
11132 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011134 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011135 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011136 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011137 if(StaParams->vhtcap_present)
11138 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011140 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
11141 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
11142 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
11143 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011144 {
11145 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011147 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011149 "[%d]: %x ", i, StaParams->supported_rates[i]);
11150 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070011151 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011152 else if ((1 == update) && (NULL == StaParams))
11153 {
11154 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11155 "%s : update is true, but staParams is NULL. Error!", __func__);
11156 return -EPERM;
11157 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011158
11159 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
11160
11161 if (!update)
11162 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011163 /*Before adding sta make sure that device exited from BMPS*/
11164 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
11165 {
11166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11167 "%s: Adding tdls peer sta. Disable BMPS", __func__);
11168 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
11169 if (status != VOS_STATUS_SUCCESS) {
11170 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
11171 }
11172 }
11173
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011174 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011175 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011176 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011177 hddLog(VOS_TRACE_LEVEL_ERROR,
11178 FL("Failed to add TDLS peer STA. Enable Bmps"));
11179 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011180 return -EPERM;
11181 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011182 }
11183 else
11184 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011185 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011186 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011187 if (ret != eHAL_STATUS_SUCCESS) {
11188 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
11189 return -EPERM;
11190 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011191 }
11192
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011193 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011194 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
11195
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011196 mutex_lock(&pHddCtx->tdls_lock);
11197 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
11198
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011199 if ((pTdlsPeer != NULL) &&
11200 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011201 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011202 hddLog(VOS_TRACE_LEVEL_ERROR,
11203 FL("peer link status %u"), pTdlsPeer->link_status);
11204 mutex_unlock(&pHddCtx->tdls_lock);
11205 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011206 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011207 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011208
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011209 if (ret <= 0)
11210 {
11211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11212 "%s: timeout waiting for tdls add station indication %ld",
11213 __func__, ret);
11214 goto error;
11215 }
11216
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011217 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
11218 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011220 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011221 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011222 }
11223
11224 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070011225
11226error:
Atul Mittal115287b2014-07-08 13:26:33 +053011227 wlan_hdd_tdls_set_link_status(pAdapter,
11228 mac,
11229 eTDLS_LINK_IDLE,
11230 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011231 return -EPERM;
11232
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011233}
11234#endif
11235
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011236static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011237 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011238#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11239 const u8 *mac,
11240#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011241 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011242#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011243 struct station_parameters *params)
11244{
11245 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011246 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011247 hdd_context_t *pHddCtx;
11248 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011249 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011250 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011251#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011252 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011253 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011254 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011255 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011256#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011257
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011258 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011259
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011260 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011261 if ((NULL == pAdapter))
11262 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011264 "invalid adapter ");
11265 return -EINVAL;
11266 }
11267
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011268 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11269 TRACE_CODE_HDD_CHANGE_STATION,
11270 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053011271 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011272
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011273 ret = wlan_hdd_validate_context(pHddCtx);
11274 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053011275 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011276 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011277 }
11278
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011279 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11280
11281 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011282 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11284 "invalid HDD station context");
11285 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011286 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011287 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
11288
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011289 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11290 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070011291 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011292 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070011293 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011294 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070011295 WLANTL_STA_AUTHENTICATED);
11296
Gopichand Nakkala29149562013-05-10 21:43:41 +053011297 if (status != VOS_STATUS_SUCCESS)
11298 {
11299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11300 "%s: Not able to change TL state to AUTHENTICATED", __func__);
11301 return -EINVAL;
11302 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011303 }
11304 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070011305 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
11306 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011307#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011308 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11309 StaParams.capability = params->capability;
11310 StaParams.uapsd_queues = params->uapsd_queues;
11311 StaParams.max_sp = params->max_sp;
11312
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011313 /* Convert (first channel , number of channels) tuple to
11314 * the total list of channels. This goes with the assumption
11315 * that if the first channel is < 14, then the next channels
11316 * are an incremental of 1 else an incremental of 4 till the number
11317 * of channels.
11318 */
11319 if (0 != params->supported_channels_len) {
11320 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11321 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11322 {
11323 int wifi_chan_index;
11324 StaParams.supported_channels[j] = params->supported_channels[i];
11325 wifi_chan_index =
11326 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11327 no_of_channels = params->supported_channels[i+1];
11328 for(k=1; k <= no_of_channels; k++)
11329 {
11330 StaParams.supported_channels[j+1] =
11331 StaParams.supported_channels[j] + wifi_chan_index;
11332 j+=1;
11333 }
11334 }
11335 StaParams.supported_channels_len = j;
11336 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053011337 if (params->supported_oper_classes_len >
11338 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
11339 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11340 "received oper classes:%d, resetting it to max supported %d",
11341 params->supported_oper_classes_len,
11342 SIR_MAC_MAX_SUPP_OPER_CLASSES);
11343 params->supported_oper_classes_len =
11344 SIR_MAC_MAX_SUPP_OPER_CLASSES;
11345 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011346 vos_mem_copy(StaParams.supported_oper_classes,
11347 params->supported_oper_classes,
11348 params->supported_oper_classes_len);
11349 StaParams.supported_oper_classes_len =
11350 params->supported_oper_classes_len;
11351
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053011352 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
11353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11354 "received extn capabilities:%d, resetting it to max supported",
11355 params->ext_capab_len);
11356 params->ext_capab_len = sizeof(StaParams.extn_capability);
11357 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011358 if (0 != params->ext_capab_len)
11359 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053011360 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011361
11362 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011363 {
11364 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011365 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011366 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011367
11368 StaParams.supported_rates_len = params->supported_rates_len;
11369
11370 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11371 * The supported_rates array , for all the structures propogating till Add Sta
11372 * to the firmware has to be modified , if the supplicant (ieee80211) is
11373 * modified to send more rates.
11374 */
11375
11376 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11377 */
11378 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11379 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11380
11381 if (0 != StaParams.supported_rates_len) {
11382 int i = 0;
11383 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11384 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011385 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011386 "Supported Rates with Length %d", StaParams.supported_rates_len);
11387 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011389 "[%d]: %0x", i, StaParams.supported_rates[i]);
11390 }
11391
11392 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011393 {
11394 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011395 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011396 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011397
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011398 if (0 != params->ext_capab_len ) {
11399 /*Define A Macro : TODO Sunil*/
11400 if ((1<<4) & StaParams.extn_capability[3]) {
11401 isBufSta = 1;
11402 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011403 /* TDLS Channel Switching Support */
11404 if ((1<<6) & StaParams.extn_capability[3]) {
11405 isOffChannelSupported = 1;
11406 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011407 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011408
11409 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053011410 (params->ht_capa || params->vht_capa ||
11411 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011412 /* TDLS Peer is WME/QoS capable */
11413 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011414
11415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11416 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
11417 __func__, isQosWmmSta, StaParams.htcap_present);
11418
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011419 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11420 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011421 isOffChannelSupported,
11422 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011423
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011424 if (VOS_STATUS_SUCCESS != status) {
11425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11426 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11427 return -EINVAL;
11428 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011429 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11430
11431 if (VOS_STATUS_SUCCESS != status) {
11432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11433 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11434 return -EINVAL;
11435 }
11436 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011437#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011438 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011439 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011440 return status;
11441}
11442
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011443#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11444static int wlan_hdd_change_station(struct wiphy *wiphy,
11445 struct net_device *dev,
11446 const u8 *mac,
11447 struct station_parameters *params)
11448#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011449static int wlan_hdd_change_station(struct wiphy *wiphy,
11450 struct net_device *dev,
11451 u8 *mac,
11452 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011453#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011454{
11455 int ret;
11456
11457 vos_ssr_protect(__func__);
11458 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11459 vos_ssr_unprotect(__func__);
11460
11461 return ret;
11462}
11463
Jeff Johnson295189b2012-06-20 16:38:30 -070011464/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011465 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011466 * This function is used to initialize the key information
11467 */
11468#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011469static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011470 struct net_device *ndev,
11471 u8 key_index, bool pairwise,
11472 const u8 *mac_addr,
11473 struct key_params *params
11474 )
11475#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011476static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011477 struct net_device *ndev,
11478 u8 key_index, const u8 *mac_addr,
11479 struct key_params *params
11480 )
11481#endif
11482{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011483 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011484 tCsrRoamSetKey setKey;
11485 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011486 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011487 v_U32_t roamId= 0xFF;
11488 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011489 hdd_hostapd_state_t *pHostapdState;
11490 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011491 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011492 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011493
11494 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011495
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011496 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11497 TRACE_CODE_HDD_CFG80211_ADD_KEY,
11498 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011499 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11500 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011501 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011502 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011503 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011504 }
11505
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011506 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11507 __func__, hdd_device_modetoString(pAdapter->device_mode),
11508 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011509
11510 if (CSR_MAX_NUM_KEY <= key_index)
11511 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011512 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011513 key_index);
11514
11515 return -EINVAL;
11516 }
11517
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011518 if (CSR_MAX_KEY_LEN < params->key_len)
11519 {
11520 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
11521 params->key_len);
11522
11523 return -EINVAL;
11524 }
11525
11526 hddLog(VOS_TRACE_LEVEL_INFO,
11527 "%s: called with key index = %d & key length %d",
11528 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011529
11530 /*extract key idx, key len and key*/
11531 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11532 setKey.keyId = key_index;
11533 setKey.keyLength = params->key_len;
11534 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
11535
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011536 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011537 {
11538 case WLAN_CIPHER_SUITE_WEP40:
11539 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11540 break;
11541
11542 case WLAN_CIPHER_SUITE_WEP104:
11543 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
11544 break;
11545
11546 case WLAN_CIPHER_SUITE_TKIP:
11547 {
11548 u8 *pKey = &setKey.Key[0];
11549 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
11550
11551 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
11552
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011553 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070011554
11555 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011556 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011557 |--------------|----------|----------|
11558 <---16bytes---><--8bytes--><--8bytes-->
11559
11560 */
11561 /*Sme expects the 32 bytes key to be in the below order
11562
11563 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011564 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011565 |--------------|----------|----------|
11566 <---16bytes---><--8bytes--><--8bytes-->
11567 */
11568 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011569 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070011570
11571 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011572 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011573
11574 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011575 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011576
11577
11578 break;
11579 }
11580
11581 case WLAN_CIPHER_SUITE_CCMP:
11582 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
11583 break;
11584
11585#ifdef FEATURE_WLAN_WAPI
11586 case WLAN_CIPHER_SUITE_SMS4:
11587 {
11588 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11589 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
11590 params->key, params->key_len);
11591 return 0;
11592 }
11593#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011594
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011595#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011596 case WLAN_CIPHER_SUITE_KRK:
11597 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
11598 break;
11599#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011600
11601#ifdef WLAN_FEATURE_11W
11602 case WLAN_CIPHER_SUITE_AES_CMAC:
11603 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070011604 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070011605#endif
11606
Jeff Johnson295189b2012-06-20 16:38:30 -070011607 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011608 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011609 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011610 status = -EOPNOTSUPP;
11611 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011612 }
11613
11614 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
11615 __func__, setKey.encType);
11616
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011617 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070011618#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11619 (!pairwise)
11620#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011621 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070011622#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011623 )
11624 {
11625 /* set group key*/
11626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11627 "%s- %d: setting Broadcast key",
11628 __func__, __LINE__);
11629 setKey.keyDirection = eSIR_RX_ONLY;
11630 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11631 }
11632 else
11633 {
11634 /* set pairwise key*/
11635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11636 "%s- %d: setting pairwise key",
11637 __func__, __LINE__);
11638 setKey.keyDirection = eSIR_TX_RX;
11639 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11640 }
11641 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
11642 {
11643 setKey.keyDirection = eSIR_TX_RX;
11644 /*Set the group key*/
11645 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11646 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070011647
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011648 if ( 0 != status )
11649 {
11650 hddLog(VOS_TRACE_LEVEL_ERROR,
11651 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011652 status = -EINVAL;
11653 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011654 }
11655 /*Save the keys here and call sme_RoamSetKey for setting
11656 the PTK after peer joins the IBSS network*/
11657 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
11658 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011659 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011660 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053011661 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
11662 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
11663 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011664 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011665 if( pHostapdState->bssState == BSS_START )
11666 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011667 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11668 vos_status = wlan_hdd_check_ula_done(pAdapter);
11669
11670 if ( vos_status != VOS_STATUS_SUCCESS )
11671 {
11672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11673 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11674 __LINE__, vos_status );
11675
11676 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11677
11678 status = -EINVAL;
11679 goto end;
11680 }
11681
Jeff Johnson295189b2012-06-20 16:38:30 -070011682 status = WLANSAP_SetKeySta( pVosContext, &setKey);
11683
11684 if ( status != eHAL_STATUS_SUCCESS )
11685 {
11686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11687 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11688 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011689 status = -EINVAL;
11690 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011691 }
11692 }
11693
11694 /* Saving WEP keys */
11695 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
11696 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
11697 {
11698 //Save the wep key in ap context. Issue setkey after the BSS is started.
11699 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11700 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
11701 }
11702 else
11703 {
11704 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011705 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011706 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
11707 }
11708 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011709 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
11710 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011711 {
11712 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11713 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11714
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011715#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11716 if (!pairwise)
11717#else
11718 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
11719#endif
11720 {
11721 /* set group key*/
11722 if (pHddStaCtx->roam_info.deferKeyComplete)
11723 {
11724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11725 "%s- %d: Perform Set key Complete",
11726 __func__, __LINE__);
11727 hdd_PerformRoamSetKeyComplete(pAdapter);
11728 }
11729 }
11730
Jeff Johnson295189b2012-06-20 16:38:30 -070011731 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
11732
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080011733 pWextState->roamProfile.Keys.defaultIndex = key_index;
11734
11735
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011736 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011737 params->key, params->key_len);
11738
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011739
Jeff Johnson295189b2012-06-20 16:38:30 -070011740 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11741
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011742 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011743 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011744 __func__, setKey.peerMac[0], setKey.peerMac[1],
11745 setKey.peerMac[2], setKey.peerMac[3],
11746 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011747 setKey.keyDirection);
11748
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011749 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053011750
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011751 if ( vos_status != VOS_STATUS_SUCCESS )
11752 {
11753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011754 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11755 __LINE__, vos_status );
11756
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011757 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011758
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011759 status = -EINVAL;
11760 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011761
11762 }
11763
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011764#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011765 /* The supplicant may attempt to set the PTK once pre-authentication
11766 is done. Save the key in the UMAC and include it in the ADD BSS
11767 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011768 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011769 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011770 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011771 hddLog(VOS_TRACE_LEVEL_INFO_MED,
11772 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011773 status = 0;
11774 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011775 }
11776 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
11777 {
11778 hddLog(VOS_TRACE_LEVEL_ERROR,
11779 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011780 status = -EINVAL;
11781 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011782 }
11783#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070011784
11785 /* issue set key request to SME*/
11786 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11787 pAdapter->sessionId, &setKey, &roamId );
11788
11789 if ( 0 != status )
11790 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011791 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011792 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
11793 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011794 status = -EINVAL;
11795 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011796 }
11797
11798
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011799 /* in case of IBSS as there was no information available about WEP keys during
11800 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070011801 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011802 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
11803 !( ( IW_AUTH_KEY_MGMT_802_1X
11804 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070011805 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
11806 )
11807 &&
11808 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
11809 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
11810 )
11811 )
11812 {
11813 setKey.keyDirection = eSIR_RX_ONLY;
11814 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11815
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011816 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011817 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011818 __func__, setKey.peerMac[0], setKey.peerMac[1],
11819 setKey.peerMac[2], setKey.peerMac[3],
11820 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011821 setKey.keyDirection);
11822
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011823 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011824 pAdapter->sessionId, &setKey, &roamId );
11825
11826 if ( 0 != status )
11827 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011828 hddLog(VOS_TRACE_LEVEL_ERROR,
11829 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011830 __func__, status);
11831 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011832 status = -EINVAL;
11833 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011834 }
11835 }
11836 }
11837
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011838end:
11839 /* Need to clear any trace of key value in the memory.
11840 * Thus zero out the memory even though it is local
11841 * variable.
11842 */
11843 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011844 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011845 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011846}
11847
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011848#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11849static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11850 struct net_device *ndev,
11851 u8 key_index, bool pairwise,
11852 const u8 *mac_addr,
11853 struct key_params *params
11854 )
11855#else
11856static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11857 struct net_device *ndev,
11858 u8 key_index, const u8 *mac_addr,
11859 struct key_params *params
11860 )
11861#endif
11862{
11863 int ret;
11864 vos_ssr_protect(__func__);
11865#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11866 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
11867 mac_addr, params);
11868#else
11869 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
11870 params);
11871#endif
11872 vos_ssr_unprotect(__func__);
11873
11874 return ret;
11875}
11876
Jeff Johnson295189b2012-06-20 16:38:30 -070011877/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011878 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011879 * This function is used to get the key information
11880 */
11881#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011882static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011883 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011884 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011885 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011886 const u8 *mac_addr, void *cookie,
11887 void (*callback)(void *cookie, struct key_params*)
11888 )
11889#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011890static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011891 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011892 struct net_device *ndev,
11893 u8 key_index, const u8 *mac_addr, void *cookie,
11894 void (*callback)(void *cookie, struct key_params*)
11895 )
11896#endif
11897{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011898 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011899 hdd_wext_state_t *pWextState = NULL;
11900 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011901 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011902 hdd_context_t *pHddCtx;
11903 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011904
11905 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011906
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011907 if (NULL == pAdapter)
11908 {
11909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11910 "%s: HDD adapter is Null", __func__);
11911 return -ENODEV;
11912 }
11913
11914 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11915 ret = wlan_hdd_validate_context(pHddCtx);
11916 if (0 != ret)
11917 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011918 return ret;
11919 }
11920
11921 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11922 pRoamProfile = &(pWextState->roamProfile);
11923
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011924 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11925 __func__, hdd_device_modetoString(pAdapter->device_mode),
11926 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011927
Jeff Johnson295189b2012-06-20 16:38:30 -070011928 memset(&params, 0, sizeof(params));
11929
11930 if (CSR_MAX_NUM_KEY <= key_index)
11931 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011932 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011933 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011934 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011935
11936 switch(pRoamProfile->EncryptionType.encryptionType[0])
11937 {
11938 case eCSR_ENCRYPT_TYPE_NONE:
11939 params.cipher = IW_AUTH_CIPHER_NONE;
11940 break;
11941
11942 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
11943 case eCSR_ENCRYPT_TYPE_WEP40:
11944 params.cipher = WLAN_CIPHER_SUITE_WEP40;
11945 break;
11946
11947 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
11948 case eCSR_ENCRYPT_TYPE_WEP104:
11949 params.cipher = WLAN_CIPHER_SUITE_WEP104;
11950 break;
11951
11952 case eCSR_ENCRYPT_TYPE_TKIP:
11953 params.cipher = WLAN_CIPHER_SUITE_TKIP;
11954 break;
11955
11956 case eCSR_ENCRYPT_TYPE_AES:
11957 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
11958 break;
11959
11960 default:
11961 params.cipher = IW_AUTH_CIPHER_NONE;
11962 break;
11963 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011964
c_hpothuaaf19692014-05-17 17:01:48 +053011965 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11966 TRACE_CODE_HDD_CFG80211_GET_KEY,
11967 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011968
Jeff Johnson295189b2012-06-20 16:38:30 -070011969 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
11970 params.seq_len = 0;
11971 params.seq = NULL;
11972 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
11973 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011974 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011975 return 0;
11976}
11977
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011978#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11979static int wlan_hdd_cfg80211_get_key(
11980 struct wiphy *wiphy,
11981 struct net_device *ndev,
11982 u8 key_index, bool pairwise,
11983 const u8 *mac_addr, void *cookie,
11984 void (*callback)(void *cookie, struct key_params*)
11985 )
11986#else
11987static int wlan_hdd_cfg80211_get_key(
11988 struct wiphy *wiphy,
11989 struct net_device *ndev,
11990 u8 key_index, const u8 *mac_addr, void *cookie,
11991 void (*callback)(void *cookie, struct key_params*)
11992 )
11993#endif
11994{
11995 int ret;
11996
11997 vos_ssr_protect(__func__);
11998#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11999 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
12000 mac_addr, cookie, callback);
12001#else
12002 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
12003 callback);
12004#endif
12005 vos_ssr_unprotect(__func__);
12006
12007 return ret;
12008}
12009
Jeff Johnson295189b2012-06-20 16:38:30 -070012010/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012011 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012012 * This function is used to delete the key information
12013 */
12014#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012015static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012016 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012017 u8 key_index,
12018 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012019 const u8 *mac_addr
12020 )
12021#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012022static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012023 struct net_device *ndev,
12024 u8 key_index,
12025 const u8 *mac_addr
12026 )
12027#endif
12028{
12029 int status = 0;
12030
12031 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012032 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070012033 //it is observed that this is invalidating peer
12034 //key index whenever re-key is done. This is affecting data link.
12035 //It should be ok to ignore del_key.
12036#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012037 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
12038 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012039 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12040 tCsrRoamSetKey setKey;
12041 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012042
Jeff Johnson295189b2012-06-20 16:38:30 -070012043 ENTER();
12044
12045 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
12046 __func__,pAdapter->device_mode);
12047
12048 if (CSR_MAX_NUM_KEY <= key_index)
12049 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012050 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012051 key_index);
12052
12053 return -EINVAL;
12054 }
12055
12056 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12057 setKey.keyId = key_index;
12058
12059 if (mac_addr)
12060 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
12061 else
12062 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
12063
12064 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
12065
12066 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012067 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012068 )
12069 {
12070
12071 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070012072 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
12073 if( pHostapdState->bssState == BSS_START)
12074 {
12075 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012076
Jeff Johnson295189b2012-06-20 16:38:30 -070012077 if ( status != eHAL_STATUS_SUCCESS )
12078 {
12079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12080 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12081 __LINE__, status );
12082 }
12083 }
12084 }
12085 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012086 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070012087 )
12088 {
12089 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12090
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012091 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12092
12093 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012094 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012095 __func__, setKey.peerMac[0], setKey.peerMac[1],
12096 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070012097 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012098 if(pAdapter->sessionCtx.station.conn_info.connState ==
12099 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070012100 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012101 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012102 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012103
Jeff Johnson295189b2012-06-20 16:38:30 -070012104 if ( 0 != status )
12105 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012106 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012107 "%s: sme_RoamSetKey failure, returned %d",
12108 __func__, status);
12109 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12110 return -EINVAL;
12111 }
12112 }
12113 }
12114#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012115 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012116 return status;
12117}
12118
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012119#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12120static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12121 struct net_device *ndev,
12122 u8 key_index,
12123 bool pairwise,
12124 const u8 *mac_addr
12125 )
12126#else
12127static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12128 struct net_device *ndev,
12129 u8 key_index,
12130 const u8 *mac_addr
12131 )
12132#endif
12133{
12134 int ret;
12135
12136 vos_ssr_protect(__func__);
12137#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12138 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
12139 mac_addr);
12140#else
12141 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
12142#endif
12143 vos_ssr_unprotect(__func__);
12144
12145 return ret;
12146}
12147
Jeff Johnson295189b2012-06-20 16:38:30 -070012148/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012149 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012150 * This function is used to set the default tx key index
12151 */
12152#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012153static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012154 struct net_device *ndev,
12155 u8 key_index,
12156 bool unicast, bool multicast)
12157#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012158static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012159 struct net_device *ndev,
12160 u8 key_index)
12161#endif
12162{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012163 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012164 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012165 hdd_wext_state_t *pWextState;
12166 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012167 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012168
12169 ENTER();
12170
Gopichand Nakkala29149562013-05-10 21:43:41 +053012171 if ((NULL == pAdapter))
12172 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012174 "invalid adapter");
12175 return -EINVAL;
12176 }
12177
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012178 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12179 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
12180 pAdapter->sessionId, key_index));
12181
Gopichand Nakkala29149562013-05-10 21:43:41 +053012182 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12183 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12184
12185 if ((NULL == pWextState) || (NULL == pHddStaCtx))
12186 {
12187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12188 "invalid Wext state or HDD context");
12189 return -EINVAL;
12190 }
12191
Arif Hussain6d2a3322013-11-17 19:50:10 -080012192 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012193 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012194
Jeff Johnson295189b2012-06-20 16:38:30 -070012195 if (CSR_MAX_NUM_KEY <= key_index)
12196 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012197 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012198 key_index);
12199
12200 return -EINVAL;
12201 }
12202
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012203 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12204 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012205 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012206 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012207 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012208 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012209
Jeff Johnson295189b2012-06-20 16:38:30 -070012210 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012211 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012212 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012213 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012214 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080012215 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012216 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080012217 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070012218 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012219 {
12220 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070012221 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012222
Jeff Johnson295189b2012-06-20 16:38:30 -070012223 tCsrRoamSetKey setKey;
12224 v_U32_t roamId= 0xFF;
12225 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012226
12227 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012228 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012229
Jeff Johnson295189b2012-06-20 16:38:30 -070012230 Keys->defaultIndex = (u8)key_index;
12231 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12232 setKey.keyId = key_index;
12233 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012234
12235 vos_mem_copy(&setKey.Key[0],
12236 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012237 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012238
Gopichand Nakkala29149562013-05-10 21:43:41 +053012239 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012240
12241 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070012242 &pHddStaCtx->conn_info.bssId[0],
12243 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012244
Gopichand Nakkala29149562013-05-10 21:43:41 +053012245 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
12246 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
12247 eCSR_ENCRYPT_TYPE_WEP104)
12248 {
12249 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
12250 even though ap is configured for WEP-40 encryption. In this canse the key length
12251 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
12252 type(104) and switching encryption type to 40*/
12253 pWextState->roamProfile.EncryptionType.encryptionType[0] =
12254 eCSR_ENCRYPT_TYPE_WEP40;
12255 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
12256 eCSR_ENCRYPT_TYPE_WEP40;
12257 }
12258
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012259 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012260 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012261
Jeff Johnson295189b2012-06-20 16:38:30 -070012262 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012263 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012264 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012265
Jeff Johnson295189b2012-06-20 16:38:30 -070012266 if ( 0 != status )
12267 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012268 hddLog(VOS_TRACE_LEVEL_ERROR,
12269 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012270 status);
12271 return -EINVAL;
12272 }
12273 }
12274 }
12275
12276 /* In SoftAp mode setting key direction for default mode */
12277 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
12278 {
12279 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
12280 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
12281 (eCSR_ENCRYPT_TYPE_AES !=
12282 pWextState->roamProfile.EncryptionType.encryptionType[0])
12283 )
12284 {
12285 /* Saving key direction for default key index to TX default */
12286 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12287 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
12288 }
12289 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012290 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012291 return status;
12292}
12293
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012294#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12295static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12296 struct net_device *ndev,
12297 u8 key_index,
12298 bool unicast, bool multicast)
12299#else
12300static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12301 struct net_device *ndev,
12302 u8 key_index)
12303#endif
12304{
12305 int ret;
12306 vos_ssr_protect(__func__);
12307#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12308 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
12309 multicast);
12310#else
12311 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
12312#endif
12313 vos_ssr_unprotect(__func__);
12314
12315 return ret;
12316}
12317
Jeff Johnson295189b2012-06-20 16:38:30 -070012318/*
12319 * FUNCTION: wlan_hdd_cfg80211_inform_bss
12320 * This function is used to inform the BSS details to nl80211 interface.
12321 */
12322static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
12323 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
12324{
12325 struct net_device *dev = pAdapter->dev;
12326 struct wireless_dev *wdev = dev->ieee80211_ptr;
12327 struct wiphy *wiphy = wdev->wiphy;
12328 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12329 int chan_no;
12330 int ie_length;
12331 const char *ie;
12332 unsigned int freq;
12333 struct ieee80211_channel *chan;
12334 int rssi = 0;
12335 struct cfg80211_bss *bss = NULL;
12336
Jeff Johnson295189b2012-06-20 16:38:30 -070012337 if( NULL == pBssDesc )
12338 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012339 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012340 return bss;
12341 }
12342
12343 chan_no = pBssDesc->channelId;
12344 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12345 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12346
12347 if( NULL == ie )
12348 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012349 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012350 return bss;
12351 }
12352
12353#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12354 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12355 {
12356 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12357 }
12358 else
12359 {
12360 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12361 }
12362#else
12363 freq = ieee80211_channel_to_frequency(chan_no);
12364#endif
12365
12366 chan = __ieee80211_get_channel(wiphy, freq);
12367
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012368 if (!chan) {
12369 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12370 return NULL;
12371 }
12372
Abhishek Singhaee43942014-06-16 18:55:47 +053012373 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012374
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012375 return cfg80211_inform_bss(wiphy, chan,
12376#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12377 CFG80211_BSS_FTYPE_UNKNOWN,
12378#endif
12379 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012380 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012381 pBssDesc->capabilityInfo,
12382 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012383 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012384}
12385
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012386/*
12387 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
12388 * interface that BSS might have been lost.
12389 * @pAdapter: adaptor
12390 * @bssid: bssid which might have been lost
12391 *
12392 * Return: bss which is unlinked from kernel cache
12393 */
12394struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
12395 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
12396{
12397 struct net_device *dev = pAdapter->dev;
12398 struct wireless_dev *wdev = dev->ieee80211_ptr;
12399 struct wiphy *wiphy = wdev->wiphy;
12400 struct cfg80211_bss *bss = NULL;
12401
Abhishek Singh5a597e62016-12-05 15:16:30 +053012402 bss = hdd_get_bss_entry(wiphy,
12403 NULL, bssid,
12404 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012405 if (bss == NULL) {
12406 hddLog(LOGE, FL("BSS not present"));
12407 } else {
12408 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
12409 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
12410 cfg80211_unlink_bss(wiphy, bss);
12411 }
12412 return bss;
12413}
Jeff Johnson295189b2012-06-20 16:38:30 -070012414
12415
12416/*
12417 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12418 * This function is used to inform the BSS details to nl80211 interface.
12419 */
12420struct cfg80211_bss*
12421wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
12422 tSirBssDescription *bss_desc
12423 )
12424{
12425 /*
12426 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
12427 already exists in bss data base of cfg80211 for that particular BSS ID.
12428 Using cfg80211_inform_bss_frame to update the bss entry instead of
12429 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
12430 now there is no possibility to get the mgmt(probe response) frame from PE,
12431 converting bss_desc to ieee80211_mgmt(probe response) and passing to
12432 cfg80211_inform_bss_frame.
12433 */
12434 struct net_device *dev = pAdapter->dev;
12435 struct wireless_dev *wdev = dev->ieee80211_ptr;
12436 struct wiphy *wiphy = wdev->wiphy;
12437 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012438#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12439 qcom_ie_age *qie_age = NULL;
12440 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12441#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012442 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012443#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012444 const char *ie =
12445 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12446 unsigned int freq;
12447 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012448 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012449 struct cfg80211_bss *bss_status = NULL;
12450 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
12451 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070012452 hdd_context_t *pHddCtx;
12453 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070012454#ifdef WLAN_OPEN_SOURCE
12455 struct timespec ts;
12456#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012457
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012458
Wilson Yangf80a0542013-10-07 13:02:37 -070012459 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12460 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070012461 if (0 != status)
12462 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012463 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012464 }
12465
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012466 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070012467 if (!mgmt)
12468 {
12469 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12470 "%s: memory allocation failed ", __func__);
12471 return NULL;
12472 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012473
Jeff Johnson295189b2012-06-20 16:38:30 -070012474 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012475
12476#ifdef WLAN_OPEN_SOURCE
12477 /* Android does not want the timestamp from the frame.
12478 Instead it wants a monotonic increasing value */
12479 get_monotonic_boottime(&ts);
12480 mgmt->u.probe_resp.timestamp =
12481 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
12482#else
12483 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012484 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
12485 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070012486
12487#endif
12488
Jeff Johnson295189b2012-06-20 16:38:30 -070012489 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
12490 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012491
12492#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12493 /* GPS Requirement: need age ie per entry. Using vendor specific. */
12494 /* Assuming this is the last IE, copy at the end */
12495 ie_length -=sizeof(qcom_ie_age);
12496 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
12497 qie_age->element_id = QCOM_VENDOR_IE_ID;
12498 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
12499 qie_age->oui_1 = QCOM_OUI1;
12500 qie_age->oui_2 = QCOM_OUI2;
12501 qie_age->oui_3 = QCOM_OUI3;
12502 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053012503 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
12504 * bss related timestamp is in units of ms. Due to this when scan results
12505 * are sent to lowi the scan age is high.To address this, send age in units
12506 * of 1/10 ms.
12507 */
12508 qie_age->age = (vos_timer_get_system_time() -
12509 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012510#endif
12511
Jeff Johnson295189b2012-06-20 16:38:30 -070012512 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053012513 if (bss_desc->fProbeRsp)
12514 {
12515 mgmt->frame_control |=
12516 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
12517 }
12518 else
12519 {
12520 mgmt->frame_control |=
12521 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
12522 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012523
12524#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012525 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012526 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
12527 {
12528 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12529 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012530 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012531 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
12532
12533 {
12534 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12535 }
12536 else
12537 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012538 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
12539 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070012540 kfree(mgmt);
12541 return NULL;
12542 }
12543#else
12544 freq = ieee80211_channel_to_frequency(chan_no);
12545#endif
12546 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012547 /*when the band is changed on the fly using the GUI, three things are done
12548 * 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)
12549 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
12550 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
12551 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
12552 * and discards the channels correponding to previous band and calls back with zero bss results.
12553 * 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
12554 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
12555 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
12556 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
12557 * So drop the bss and continue to next bss.
12558 */
12559 if(chan == NULL)
12560 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053012561 hddLog(VOS_TRACE_LEVEL_ERROR,
12562 FL("chan pointer is NULL, chan_no: %d freq: %d"),
12563 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070012564 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012565 return NULL;
12566 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053012567 /*To keep the rssi icon of the connected AP in the scan window
12568 *and the rssi icon of the wireless networks in sync
12569 * */
12570 if (( eConnectionState_Associated ==
12571 pAdapter->sessionCtx.station.conn_info.connState ) &&
12572 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
12573 pAdapter->sessionCtx.station.conn_info.bssId,
12574 WNI_CFG_BSSID_LEN)) &&
12575 (pHddCtx->hdd_wlan_suspended == FALSE))
12576 {
12577 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
12578 rssi = (pAdapter->rssi * 100);
12579 }
12580 else
12581 {
12582 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
12583 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012584
Nirav Shah20ac06f2013-12-12 18:14:06 +053012585 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053012586 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
12587 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053012588
Jeff Johnson295189b2012-06-20 16:38:30 -070012589 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
12590 frame_len, rssi, GFP_KERNEL);
12591 kfree(mgmt);
12592 return bss_status;
12593}
12594
12595/*
12596 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
12597 * This function is used to update the BSS data base of CFG8011
12598 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012599struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012600 tCsrRoamInfo *pRoamInfo
12601 )
12602{
12603 tCsrRoamConnectedProfile roamProfile;
12604 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12605 struct cfg80211_bss *bss = NULL;
12606
12607 ENTER();
12608
12609 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
12610 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
12611
12612 if (NULL != roamProfile.pBssDesc)
12613 {
Girish Gowlif4b68022014-08-28 23:18:57 +053012614 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12615 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070012616
12617 if (NULL == bss)
12618 {
12619 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
12620 __func__);
12621 }
12622
12623 sme_RoamFreeConnectProfile(hHal, &roamProfile);
12624 }
12625 else
12626 {
12627 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
12628 __func__);
12629 }
12630 return bss;
12631}
12632
12633/*
12634 * FUNCTION: wlan_hdd_cfg80211_update_bss
12635 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012636static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
12637 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070012638 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012639{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012640 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012641 tCsrScanResultInfo *pScanResult;
12642 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012643 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012644 tScanResultHandle pResult;
12645 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012646 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012647 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012648 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012649
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012650 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12651 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
12652 NO_SESSION, pAdapter->sessionId));
12653
Wilson Yangf80a0542013-10-07 13:02:37 -070012654 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012655 ret = wlan_hdd_validate_context(pHddCtx);
12656 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070012657 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012658 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070012659 }
12660
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012661 if (pAdapter->request != NULL)
12662 {
12663 if ((pAdapter->request->n_ssids == 1)
12664 && (pAdapter->request->ssids != NULL)
12665 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
12666 is_p2p_scan = true;
12667 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012668 /*
12669 * start getting scan results and populate cgf80211 BSS database
12670 */
12671 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
12672
12673 /* no scan results */
12674 if (NULL == pResult)
12675 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012676 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
12677 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012678 wlan_hdd_get_frame_logs(pAdapter,
12679 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070012680 return status;
12681 }
12682
12683 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
12684
12685 while (pScanResult)
12686 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012687 /*
12688 * cfg80211_inform_bss() is not updating ie field of bss entry, if
12689 * entry already exists in bss data base of cfg80211 for that
12690 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
12691 * bss entry instead of cfg80211_inform_bss, But this call expects
12692 * mgmt packet as input. As of now there is no possibility to get
12693 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070012694 * ieee80211_mgmt(probe response) and passing to c
12695 * fg80211_inform_bss_frame.
12696 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012697 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
12698 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
12699 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012700 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12701 continue; //Skip the non p2p bss entries
12702 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012703 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12704 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012705
Jeff Johnson295189b2012-06-20 16:38:30 -070012706
12707 if (NULL == bss_status)
12708 {
12709 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012710 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012711 }
12712 else
12713 {
Yue Maf49ba872013-08-19 12:04:25 -070012714 cfg80211_put_bss(
12715#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
12716 wiphy,
12717#endif
12718 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012719 }
12720
12721 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12722 }
12723
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012724 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012725 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012726 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012727}
12728
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012729void
12730hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
12731{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012732 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080012733 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012734} /****** end hddPrintMacAddr() ******/
12735
12736void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012737hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012738{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012739 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012740 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012741 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
12742 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
12743 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012744} /****** end hddPrintPmkId() ******/
12745
12746//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
12747//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
12748
12749//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
12750//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
12751
12752#define dump_bssid(bssid) \
12753 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012754 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
12755 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012756 }
12757
12758#define dump_pmkid(pMac, pmkid) \
12759 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012760 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
12761 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012762 }
12763
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070012764#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012765/*
12766 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
12767 * This function is used to notify the supplicant of a new PMKSA candidate.
12768 */
12769int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012770 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012771 int index, bool preauth )
12772{
Jeff Johnsone7245742012-09-05 17:12:55 -070012773#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012774 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012775 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012776
12777 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070012778 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012779
12780 if( NULL == pRoamInfo )
12781 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012782 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012783 return -EINVAL;
12784 }
12785
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012786 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
12787 {
12788 dump_bssid(pRoamInfo->bssid);
12789 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012790 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012791 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012792#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012793 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012794}
12795#endif //FEATURE_WLAN_LFR
12796
Yue Maef608272013-04-08 23:09:17 -070012797#ifdef FEATURE_WLAN_LFR_METRICS
12798/*
12799 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
12800 * 802.11r/LFR metrics reporting function to report preauth initiation
12801 *
12802 */
12803#define MAX_LFR_METRICS_EVENT_LENGTH 100
12804VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
12805 tCsrRoamInfo *pRoamInfo)
12806{
12807 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12808 union iwreq_data wrqu;
12809
12810 ENTER();
12811
12812 if (NULL == pAdapter)
12813 {
12814 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12815 return VOS_STATUS_E_FAILURE;
12816 }
12817
12818 /* create the event */
12819 memset(&wrqu, 0, sizeof(wrqu));
12820 memset(metrics_notification, 0, sizeof(metrics_notification));
12821
12822 wrqu.data.pointer = metrics_notification;
12823 wrqu.data.length = scnprintf(metrics_notification,
12824 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
12825 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12826
12827 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12828
12829 EXIT();
12830
12831 return VOS_STATUS_SUCCESS;
12832}
12833
12834/*
12835 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
12836 * 802.11r/LFR metrics reporting function to report preauth completion
12837 * or failure
12838 */
12839VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
12840 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
12841{
12842 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12843 union iwreq_data wrqu;
12844
12845 ENTER();
12846
12847 if (NULL == pAdapter)
12848 {
12849 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12850 return VOS_STATUS_E_FAILURE;
12851 }
12852
12853 /* create the event */
12854 memset(&wrqu, 0, sizeof(wrqu));
12855 memset(metrics_notification, 0, sizeof(metrics_notification));
12856
12857 scnprintf(metrics_notification, sizeof(metrics_notification),
12858 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
12859 MAC_ADDR_ARRAY(pRoamInfo->bssid));
12860
12861 if (1 == preauth_status)
12862 strncat(metrics_notification, " TRUE", 5);
12863 else
12864 strncat(metrics_notification, " FALSE", 6);
12865
12866 wrqu.data.pointer = metrics_notification;
12867 wrqu.data.length = strlen(metrics_notification);
12868
12869 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12870
12871 EXIT();
12872
12873 return VOS_STATUS_SUCCESS;
12874}
12875
12876/*
12877 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
12878 * 802.11r/LFR metrics reporting function to report handover initiation
12879 *
12880 */
12881VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
12882 tCsrRoamInfo *pRoamInfo)
12883{
12884 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12885 union iwreq_data wrqu;
12886
12887 ENTER();
12888
12889 if (NULL == pAdapter)
12890 {
12891 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12892 return VOS_STATUS_E_FAILURE;
12893 }
12894
12895 /* create the event */
12896 memset(&wrqu, 0, sizeof(wrqu));
12897 memset(metrics_notification, 0, sizeof(metrics_notification));
12898
12899 wrqu.data.pointer = metrics_notification;
12900 wrqu.data.length = scnprintf(metrics_notification,
12901 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
12902 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12903
12904 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12905
12906 EXIT();
12907
12908 return VOS_STATUS_SUCCESS;
12909}
12910#endif
12911
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012912
12913/**
12914 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
12915 * @scan_req: scan request to be checked
12916 *
12917 * Return: true or false
12918 */
12919#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
12920static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
12921 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053012922 *scan_req, hdd_context_t
12923 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012924{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053012925 if (!scan_req || !scan_req->wiphy ||
12926 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012927 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
12928 return false;
12929 }
12930 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
12931 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
12932 return false;
12933 }
12934 return true;
12935}
12936#else
12937static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
12938 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053012939 *scan_req, hdd_context_t
12940 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012941{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053012942 if (!scan_req || !scan_req->wiphy ||
12943 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012944 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
12945 return false;
12946 }
12947 return true;
12948}
12949#endif
12950
12951
Jeff Johnson295189b2012-06-20 16:38:30 -070012952/*
12953 * FUNCTION: hdd_cfg80211_scan_done_callback
12954 * scanning callback function, called after finishing scan
12955 *
12956 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012957static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070012958 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
12959{
12960 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012961 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012962 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012963 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012964 struct cfg80211_scan_request *req = NULL;
12965 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012966 bool aborted = false;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012967#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12968 bool iface_down = false;
12969#endif
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012970 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012971 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012972 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012973
12974 ENTER();
12975
c_manjee1b4ab9a2016-10-26 11:36:55 +053012976 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
12977 !pAdapter->dev) {
12978 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
12979 return 0;
12980 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012981 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012982 if (NULL == pHddCtx) {
12983 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012984 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012985 }
12986
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012987#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12988 if (!(pAdapter->dev->flags & IFF_UP))
12989 {
12990 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012991 iface_down = true;
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012992 }
12993#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012994 pScanInfo = &pHddCtx->scan_info;
12995
Jeff Johnson295189b2012-06-20 16:38:30 -070012996 hddLog(VOS_TRACE_LEVEL_INFO,
12997 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012998 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012999 __func__, halHandle, pContext, (int) scanId, (int) status);
13000
Kiet Lamac06e2c2013-10-23 16:25:07 +053013001 pScanInfo->mScanPendingCounter = 0;
13002
Jeff Johnson295189b2012-06-20 16:38:30 -070013003 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013004 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070013005 &pScanInfo->scan_req_completion_event,
13006 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013007 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070013008 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013009 hddLog(VOS_TRACE_LEVEL_ERROR,
13010 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070013011 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013012 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013013 }
13014
Yue Maef608272013-04-08 23:09:17 -070013015 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070013016 {
13017 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013018 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013019 }
13020
13021 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013022 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070013023 {
13024 hddLog(VOS_TRACE_LEVEL_INFO,
13025 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080013026 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070013027 (int) scanId);
13028 }
13029
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013030#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013031 if (!iface_down)
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013032#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013033 {
13034 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
13035 pAdapter);
13036 if (0 > ret)
13037 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013038 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013039
Jeff Johnson295189b2012-06-20 16:38:30 -070013040 /* If any client wait scan result through WEXT
13041 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013042 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070013043 {
13044 /* The other scan request waiting for current scan finish
13045 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013046 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013047 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013048 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070013049 }
13050 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013051 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013052 {
13053 struct net_device *dev = pAdapter->dev;
13054 union iwreq_data wrqu;
13055 int we_event;
13056 char *msg;
13057
13058 memset(&wrqu, '\0', sizeof(wrqu));
13059 we_event = SIOCGIWSCAN;
13060 msg = NULL;
13061 wireless_send_event(dev, we_event, &wrqu, msg);
13062 }
13063 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013064 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013065
13066 /* Get the Scan Req */
13067 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053013068 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013069
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013070 /* Scan is no longer pending */
13071 pScanInfo->mScanPending = VOS_FALSE;
13072
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013073 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070013074 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013075#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13076 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
13077 iface_down ? "up" : "down");
13078#endif
13079
13080 if (pAdapter->dev) {
13081 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
13082 pAdapter->dev->name);
13083 }
mukul sharmae7041822015-12-03 15:09:21 +053013084 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070013085 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013086 }
13087
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013088 /* last_scan_timestamp is used to decide if new scan
13089 * is needed or not on station interface. If last station
13090 * scan time and new station scan time is less then
13091 * last_scan_timestamp ; driver will return cached scan.
13092 */
13093 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
13094 {
13095 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
13096
13097 if ( req->n_channels )
13098 {
13099 for (i = 0; i < req->n_channels ; i++ )
13100 {
13101 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
13102 }
13103 /* store no of channel scanned */
13104 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
13105 }
13106
13107 }
13108
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070013109 /*
13110 * cfg80211_scan_done informing NL80211 about completion
13111 * of scanning
13112 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013113 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
13114 {
13115 aborted = true;
13116 }
mukul sharmae7041822015-12-03 15:09:21 +053013117
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013118#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13119 if (!iface_down)
13120#endif
13121 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053013122
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013123 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070013124
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013125allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013126 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
13127 ) && (pHddCtx->spoofMacAddr.isEnabled
13128 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053013129 /* Generate new random mac addr for next scan */
13130 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053013131
13132 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
13133 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053013134 }
13135
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013136 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013137 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013138
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013139 /* Acquire wakelock to handle the case where APP's tries to suspend
13140 * immediatly after the driver gets connect request(i.e after scan)
13141 * from supplicant, this result in app's is suspending and not able
13142 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013143 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013144
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013145#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13146 if (!iface_down)
13147#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013148#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013149 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013150#endif
13151
Jeff Johnson295189b2012-06-20 16:38:30 -070013152 EXIT();
13153 return 0;
13154}
13155
13156/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053013157 * FUNCTION: hdd_isConnectionInProgress
13158 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013159 *
13160 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013161v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
13162 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013163{
13164 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13165 hdd_station_ctx_t *pHddStaCtx = NULL;
13166 hdd_adapter_t *pAdapter = NULL;
13167 VOS_STATUS status = 0;
13168 v_U8_t staId = 0;
13169 v_U8_t *staMac = NULL;
13170
13171 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13172
13173 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13174 {
13175 pAdapter = pAdapterNode->pAdapter;
13176
13177 if( pAdapter )
13178 {
13179 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013180 "%s: Adapter with device mode %s (%d) exists",
13181 __func__, hdd_device_modetoString(pAdapter->device_mode),
13182 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013183 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053013184 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13185 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
13186 (eConnectionState_Connecting ==
13187 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13188 {
13189 hddLog(VOS_TRACE_LEVEL_ERROR,
13190 "%s: %p(%d) Connection is in progress", __func__,
13191 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013192 if (session_id && reason)
13193 {
13194 *session_id = pAdapter->sessionId;
13195 *reason = eHDD_CONNECTION_IN_PROGRESS;
13196 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013197 return VOS_TRUE;
13198 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013199 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053013200 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013201 {
13202 hddLog(VOS_TRACE_LEVEL_ERROR,
13203 "%s: %p(%d) Reassociation is in progress", __func__,
13204 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013205 if (session_id && reason)
13206 {
13207 *session_id = pAdapter->sessionId;
13208 *reason = eHDD_REASSOC_IN_PROGRESS;
13209 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013210 return VOS_TRUE;
13211 }
13212 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013213 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13214 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013215 {
13216 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13217 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013218 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013219 {
13220 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
13221 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013222 "%s: client " MAC_ADDRESS_STR
13223 " is in the middle of WPS/EAPOL exchange.", __func__,
13224 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013225 if (session_id && reason)
13226 {
13227 *session_id = pAdapter->sessionId;
13228 *reason = eHDD_EAPOL_IN_PROGRESS;
13229 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013230 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013231 }
13232 }
13233 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
13234 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
13235 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013236 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13237 ptSapContext pSapCtx = NULL;
13238 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13239 if(pSapCtx == NULL){
13240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13241 FL("psapCtx is NULL"));
13242 return VOS_FALSE;
13243 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013244 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
13245 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013246 if ((pSapCtx->aStaInfo[staId].isUsed) &&
13247 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013248 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013249 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013250
13251 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013252 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
13253 "middle of WPS/EAPOL exchange.", __func__,
13254 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013255 if (session_id && reason)
13256 {
13257 *session_id = pAdapter->sessionId;
13258 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
13259 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013260 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013261 }
13262 }
13263 }
13264 }
13265 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13266 pAdapterNode = pNext;
13267 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013268 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013269}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013270
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013271/**
13272 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
13273 * to the Scan request
13274 * @scanRequest: Pointer to the csr scan request
13275 * @request: Pointer to the scan request from supplicant
13276 *
13277 * Return: None
13278 */
13279#ifdef CFG80211_SCAN_BSSID
13280static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13281 struct cfg80211_scan_request *request)
13282{
13283 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
13284}
13285#else
13286static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13287 struct cfg80211_scan_request *request)
13288{
13289}
13290#endif
13291
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013292/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013293 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070013294 * this scan respond to scan trigger and update cfg80211 scan database
13295 * later, scan dump command can be used to recieve scan results
13296 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013297int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013298#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13299 struct net_device *dev,
13300#endif
13301 struct cfg80211_scan_request *request)
13302{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013303 hdd_adapter_t *pAdapter = NULL;
13304 hdd_context_t *pHddCtx = NULL;
13305 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013306 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013307 tCsrScanRequest scanRequest;
13308 tANI_U8 *channelList = NULL, i;
13309 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013310 int status;
13311 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013312 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013313 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053013314 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013315 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013316 v_U8_t curr_session_id;
13317 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070013318
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013319#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
13320 struct net_device *dev = NULL;
13321 if (NULL == request)
13322 {
13323 hddLog(VOS_TRACE_LEVEL_ERROR,
13324 "%s: scan req param null", __func__);
13325 return -EINVAL;
13326 }
13327 dev = request->wdev->netdev;
13328#endif
13329
13330 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13331 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
13332 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13333
Jeff Johnson295189b2012-06-20 16:38:30 -070013334 ENTER();
13335
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013336 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13337 __func__, hdd_device_modetoString(pAdapter->device_mode),
13338 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013339
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013340 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013341 if (0 != status)
13342 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013343 return status;
13344 }
13345
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013346 if (NULL == pwextBuf)
13347 {
13348 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
13349 __func__);
13350 return -EIO;
13351 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013352 cfg_param = pHddCtx->cfg_ini;
13353 pScanInfo = &pHddCtx->scan_info;
13354
Jeff Johnson295189b2012-06-20 16:38:30 -070013355#ifdef WLAN_BTAMP_FEATURE
13356 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013357 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070013358 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013359 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013360 "%s: No scanning when AMP is on", __func__);
13361 return -EOPNOTSUPP;
13362 }
13363#endif
13364 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013365 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013366 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013367 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013368 "%s: Not scanning on device_mode = %s (%d)",
13369 __func__, hdd_device_modetoString(pAdapter->device_mode),
13370 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013371 return -EOPNOTSUPP;
13372 }
13373
13374 if (TRUE == pScanInfo->mScanPending)
13375 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013376 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
13377 {
13378 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
13379 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013380 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013381 }
13382
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053013383 // Don't allow scan if PNO scan is going on.
13384 if (pHddCtx->isPnoEnable)
13385 {
13386 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13387 FL("pno scan in progress"));
13388 return -EBUSY;
13389 }
13390
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013391 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070013392 //Channel and action frame is pending
13393 //Otherwise Cancel Remain On Channel and allow Scan
13394 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013395 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070013396 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013397 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070013398 return -EBUSY;
13399 }
13400
Jeff Johnson295189b2012-06-20 16:38:30 -070013401 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
13402 {
13403 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080013404 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013405 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013406 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013407 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
13408 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013409 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013410 "%s: MAX TM Level Scan not allowed", __func__);
13411 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013412 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013413 }
13414 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
13415
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013416 /* Check if scan is allowed at this point of time.
13417 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053013418 if (TRUE == pHddCtx->btCoexModeSet)
13419 {
13420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13421 FL("BTCoex Mode operation in progress"));
13422 return -EBUSY;
13423 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013424 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013425 {
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013426 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Scan not allowed"));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013427 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
13428 pHddCtx->last_scan_reject_reason != curr_reason ||
13429 !pHddCtx->last_scan_reject_timestamp)
13430 {
13431 pHddCtx->last_scan_reject_session_id = curr_session_id;
13432 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053013433 pHddCtx->last_scan_reject_timestamp =
13434 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053013435 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013436 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053013437 else
13438 {
13439 pHddCtx->scan_reject_cnt++;
13440
Abhishek Singh3e500772017-07-17 10:13:43 +053013441 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
13442 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
13443 vos_system_time_after(jiffies_to_msecs(jiffies),
Abhishek Singhe4b12562017-06-20 16:53:39 +053013444 pHddCtx->last_scan_reject_timestamp));
13445
13446 if ((pHddCtx->scan_reject_cnt >=
13447 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053013448 vos_system_time_after(jiffies_to_msecs(jiffies),
13449 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013450 {
13451 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053013452 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013453 if (pHddCtx->cfg_ini->enableFatalEvent)
13454 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
13455 WLAN_LOG_INDICATOR_HOST_DRIVER,
13456 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
13457 FALSE, FALSE);
13458 else
13459 {
13460 hddLog(LOGE, FL("Triggering SSR"));
13461 vos_wlanRestart();
13462 }
13463 }
13464 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013465 return -EBUSY;
13466 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013467 pHddCtx->last_scan_reject_timestamp = 0;
13468 pHddCtx->last_scan_reject_session_id = 0xFF;
13469 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053013470 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013471
Jeff Johnson295189b2012-06-20 16:38:30 -070013472 vos_mem_zero( &scanRequest, sizeof(scanRequest));
13473
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013474 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
13475 * Becasue of this, driver is assuming that this is not wildcard scan and so
13476 * is not aging out the scan results.
13477 */
13478 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070013479 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013480 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013481 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013482
13483 if ((request->ssids) && (0 < request->n_ssids))
13484 {
13485 tCsrSSIDInfo *SsidInfo;
13486 int j;
13487 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
13488 /* Allocate num_ssid tCsrSSIDInfo structure */
13489 SsidInfo = scanRequest.SSIDs.SSIDList =
13490 ( tCsrSSIDInfo *)vos_mem_malloc(
13491 request->n_ssids*sizeof(tCsrSSIDInfo));
13492
13493 if(NULL == scanRequest.SSIDs.SSIDList)
13494 {
13495 hddLog(VOS_TRACE_LEVEL_ERROR,
13496 "%s: memory alloc failed SSIDInfo buffer", __func__);
13497 return -ENOMEM;
13498 }
13499
13500 /* copy all the ssid's and their length */
13501 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
13502 {
13503 /* get the ssid length */
13504 SsidInfo->SSID.length = request->ssids[j].ssid_len;
13505 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
13506 SsidInfo->SSID.length);
13507 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
13508 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
13509 j, SsidInfo->SSID.ssId);
13510 }
13511 /* set the scan type to active */
13512 scanRequest.scanType = eSIR_ACTIVE_SCAN;
13513 }
13514 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013515 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013516 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13517 TRACE_CODE_HDD_CFG80211_SCAN,
13518 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070013519 /* set the scan type to active */
13520 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070013521 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013522 else
13523 {
13524 /*Set the scan type to default type, in this case it is ACTIVE*/
13525 scanRequest.scanType = pScanInfo->scan_mode;
13526 }
13527 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
13528 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070013529
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013530 csr_scan_request_assign_bssid(&scanRequest, request);
13531
Jeff Johnson295189b2012-06-20 16:38:30 -070013532 /* set BSSType to default type */
13533 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
13534
13535 /*TODO: scan the requested channels only*/
13536
13537 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013538 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070013539 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013540 hddLog(VOS_TRACE_LEVEL_WARN,
13541 "No of Scan Channels exceeded limit: %d", request->n_channels);
13542 request->n_channels = MAX_CHANNEL;
13543 }
13544
13545 hddLog(VOS_TRACE_LEVEL_INFO,
13546 "No of Scan Channels: %d", request->n_channels);
13547
13548
13549 if( request->n_channels )
13550 {
13551 char chList [(request->n_channels*5)+1];
13552 int len;
13553 channelList = vos_mem_malloc( request->n_channels );
13554 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053013555 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013556 hddLog(VOS_TRACE_LEVEL_ERROR,
13557 "%s: memory alloc failed channelList", __func__);
13558 status = -ENOMEM;
13559 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053013560 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013561
13562 for( i = 0, len = 0; i < request->n_channels ; i++ )
13563 {
13564 channelList[i] = request->channels[i]->hw_value;
13565 len += snprintf(chList+len, 5, "%d ", channelList[i]);
13566 }
13567
Nirav Shah20ac06f2013-12-12 18:14:06 +053013568 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013569 "Channel-List: %s ", chList);
13570 }
c_hpothu53512302014-04-15 18:49:53 +053013571
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013572 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
13573 scanRequest.ChannelInfo.ChannelList = channelList;
13574
13575 /* set requestType to full scan */
13576 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
13577
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013578 /* if there is back to back scan happening in driver with in
13579 * nDeferScanTimeInterval interval driver should defer new scan request
13580 * and should provide last cached scan results instead of new channel list.
13581 * This rule is not applicable if scan is p2p scan.
13582 * This condition will work only in case when last request no of channels
13583 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053013584 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053013585 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013586 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013587
Sushant Kaushik86592172015-04-27 16:35:03 +053013588 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
13589 /* if wps ie is NULL , then only defer scan */
13590 if ( pWpsIe == NULL &&
13591 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053013592 {
13593 if ( pScanInfo->last_scan_timestamp !=0 &&
13594 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
13595 {
13596 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
13597 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
13598 vos_mem_compare(pScanInfo->last_scan_channelList,
13599 channelList, pScanInfo->last_scan_numChannels))
13600 {
13601 hddLog(VOS_TRACE_LEVEL_WARN,
13602 " New and old station scan time differ is less then %u",
13603 pHddCtx->cfg_ini->nDeferScanTimeInterval);
13604
13605 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013606 pAdapter);
13607
Agarwal Ashish57e84372014-12-05 18:26:53 +053013608 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013609 "Return old cached scan as all channels and no of channels are same");
13610
Agarwal Ashish57e84372014-12-05 18:26:53 +053013611 if (0 > ret)
13612 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013613
Agarwal Ashish57e84372014-12-05 18:26:53 +053013614 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013615
13616 status = eHAL_STATUS_SUCCESS;
13617 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053013618 }
13619 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013620 }
13621
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013622 /* Flush the scan results(only p2p beacons) for STA scan and P2P
13623 * search (Flush on both full scan and social scan but not on single
13624 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
13625 */
13626
13627 /* Supplicant does single channel scan after 8-way handshake
13628 * and in that case driver shoudnt flush scan results. If
13629 * driver flushes the scan results here and unfortunately if
13630 * the AP doesnt respond to our probe req then association
13631 * fails which is not desired
13632 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013633 if ((request->n_ssids == 1)
13634 && (request->ssids != NULL)
13635 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13636 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013637
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013638 if( is_p2p_scan ||
13639 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013640 {
13641 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13642 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13643 pAdapter->sessionId );
13644 }
13645
13646 if( request->ie_len )
13647 {
13648 /* save this for future association (join requires this) */
13649 /*TODO: Array needs to be converted to dynamic allocation,
13650 * as multiple ie.s can be sent in cfg80211_scan_request structure
13651 * CR 597966
13652 */
13653 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13654 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13655 pScanInfo->scanAddIE.length = request->ie_len;
13656
13657 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13658 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13659 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013660 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013661 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013662 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013663 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13664 memcpy( pwextBuf->roamProfile.addIEScan,
13665 request->ie, request->ie_len);
13666 }
13667 else
13668 {
13669 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13670 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013671 }
13672
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013673 }
13674 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13675 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13676
13677 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13678 request->ie_len);
13679 if (pP2pIe != NULL)
13680 {
13681#ifdef WLAN_FEATURE_P2P_DEBUG
13682 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13683 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13684 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013685 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013686 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13687 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13688 "Go nego completed to Connection is started");
13689 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13690 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013691 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013692 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13693 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013694 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013695 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13696 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13697 "Disconnected state to Connection is started");
13698 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13699 "for 4way Handshake");
13700 }
13701#endif
13702
13703 /* no_cck will be set during p2p find to disable 11b rates */
13704 if(TRUE == request->no_cck)
13705 {
13706 hddLog(VOS_TRACE_LEVEL_INFO,
13707 "%s: This is a P2P Search", __func__);
13708 scanRequest.p2pSearch = 1;
13709
13710 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013711 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013712 /* set requestType to P2P Discovery */
13713 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13714 }
13715
13716 /*
13717 Skip Dfs Channel in case of P2P Search
13718 if it is set in ini file
13719 */
13720 if(cfg_param->skipDfsChnlInP2pSearch)
13721 {
13722 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013723 }
13724 else
13725 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013726 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013727 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013728
Agarwal Ashish4f616132013-12-30 23:32:50 +053013729 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013730 }
13731 }
13732
13733 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13734
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013735#ifdef FEATURE_WLAN_TDLS
13736 /* if tdls disagree scan right now, return immediately.
13737 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13738 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13739 */
13740 status = wlan_hdd_tdls_scan_callback (pAdapter,
13741 wiphy,
13742#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13743 dev,
13744#endif
13745 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013746 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013747 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053013748 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013749 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13750 "scan rejected %d", __func__, status);
13751 else
13752 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13753 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013754 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053013755 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013756 }
13757#endif
13758
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013759 /* acquire the wakelock to avoid the apps suspend during the scan. To
13760 * address the following issues.
13761 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13762 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13763 * for long time, this result in apps running at full power for long time.
13764 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13765 * be stuck in full power because of resume BMPS
13766 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013767 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013768
Nirav Shah20ac06f2013-12-12 18:14:06 +053013769 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13770 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013771 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13772 scanRequest.requestType, scanRequest.scanType,
13773 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013774 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13775
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013776 if (pHddCtx->spoofMacAddr.isEnabled &&
13777 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053013778 {
13779 hddLog(VOS_TRACE_LEVEL_INFO,
13780 "%s: MAC Spoofing enabled for current scan", __func__);
13781 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13782 * to fill TxBds for probe request during current scan
13783 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013784 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013785 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013786
13787 if(status != VOS_STATUS_SUCCESS)
13788 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013789 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013790 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013791#ifdef FEATURE_WLAN_TDLS
13792 wlan_hdd_tdls_scan_done_callback(pAdapter);
13793#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013794 goto free_mem;
13795 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013796 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013797 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013798 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013799 pAdapter->sessionId, &scanRequest, &scanId,
13800 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013801
Jeff Johnson295189b2012-06-20 16:38:30 -070013802 if (eHAL_STATUS_SUCCESS != status)
13803 {
13804 hddLog(VOS_TRACE_LEVEL_ERROR,
13805 "%s: sme_ScanRequest returned error %d", __func__, status);
13806 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013807 if(eHAL_STATUS_RESOURCES == status)
13808 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013809 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13810 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013811 status = -EBUSY;
13812 } else {
13813 status = -EIO;
13814 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013815 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013816
13817#ifdef FEATURE_WLAN_TDLS
13818 wlan_hdd_tdls_scan_done_callback(pAdapter);
13819#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013820 goto free_mem;
13821 }
13822
13823 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013824 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013825 pAdapter->request = request;
13826 pScanInfo->scanId = scanId;
13827
13828 complete(&pScanInfo->scan_req_completion_event);
13829
13830free_mem:
13831 if( scanRequest.SSIDs.SSIDList )
13832 {
13833 vos_mem_free(scanRequest.SSIDs.SSIDList);
13834 }
13835
13836 if( channelList )
13837 vos_mem_free( channelList );
13838
13839 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013840 return status;
13841}
13842
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013843int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13844#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13845 struct net_device *dev,
13846#endif
13847 struct cfg80211_scan_request *request)
13848{
13849 int ret;
13850
13851 vos_ssr_protect(__func__);
13852 ret = __wlan_hdd_cfg80211_scan(wiphy,
13853#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13854 dev,
13855#endif
13856 request);
13857 vos_ssr_unprotect(__func__);
13858
13859 return ret;
13860}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013861
13862void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13863{
13864 v_U8_t iniDot11Mode =
13865 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13866 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13867
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013868 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13869 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013870 switch ( iniDot11Mode )
13871 {
13872 case eHDD_DOT11_MODE_AUTO:
13873 case eHDD_DOT11_MODE_11ac:
13874 case eHDD_DOT11_MODE_11ac_ONLY:
13875#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013876 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13877 sme_IsFeatureSupportedByFW(DOT11AC) )
13878 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13879 else
13880 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013881#else
13882 hddDot11Mode = eHDD_DOT11_MODE_11n;
13883#endif
13884 break;
13885 case eHDD_DOT11_MODE_11n:
13886 case eHDD_DOT11_MODE_11n_ONLY:
13887 hddDot11Mode = eHDD_DOT11_MODE_11n;
13888 break;
13889 default:
13890 hddDot11Mode = iniDot11Mode;
13891 break;
13892 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013893#ifdef WLAN_FEATURE_AP_HT40_24G
13894 if (operationChannel > SIR_11B_CHANNEL_END)
13895#endif
13896 {
13897 /* This call decides required channel bonding mode */
13898 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013899 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13900 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013901 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013902}
13903
Jeff Johnson295189b2012-06-20 16:38:30 -070013904/*
13905 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013906 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013907 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013908int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013909 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13910 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013911{
13912 int status = 0;
13913 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013914 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013915 v_U32_t roamId;
13916 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013917 eCsrAuthType RSNAuthType;
13918
13919 ENTER();
13920
13921 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013922 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13923
13924 status = wlan_hdd_validate_context(pHddCtx);
13925 if (status)
13926 {
Yue Mae36e3552014-03-05 17:06:20 -080013927 return status;
13928 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013929
Jeff Johnson295189b2012-06-20 16:38:30 -070013930 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13931 {
13932 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13933 return -EINVAL;
13934 }
13935
Nitesh Shah9b066282017-06-06 18:05:52 +053013936 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
13937
Jeff Johnson295189b2012-06-20 16:38:30 -070013938 pRoamProfile = &pWextState->roamProfile;
13939
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013940 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013941 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013942 hdd_station_ctx_t *pHddStaCtx;
13943 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053013944 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013945
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013946 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13947
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013948 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013949 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13950 {
13951 /*QoS not enabled in cfg file*/
13952 pRoamProfile->uapsd_mask = 0;
13953 }
13954 else
13955 {
13956 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013957 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013958 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13959 }
13960
13961 pRoamProfile->SSIDs.numOfSSIDs = 1;
13962 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13963 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013964 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013965 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13966 ssid, ssid_len);
13967
Abhishek Singhb3e376c2017-01-04 15:27:13 +053013968 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
13969 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
13970
Jeff Johnson295189b2012-06-20 16:38:30 -070013971 if (bssid)
13972 {
13973 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053013974 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013975 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013976 /* Save BSSID in seperate variable as well, as RoamProfile
13977 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013978 case of join failure we should send valid BSSID to supplicant
13979 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053013980 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013981 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053013982
Jeff Johnson295189b2012-06-20 16:38:30 -070013983 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053013984 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070013985 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053013986 /* Store bssid_hint to use in the scan filter. */
13987 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
13988 WNI_CFG_BSSID_LEN);
13989 /*
13990 * Save BSSID in seperate variable as well, as RoamProfile
13991 * BSSID is getting zeroed out in the association process. And in
13992 * case of join failure we should send valid BSSID to supplicant
13993 */
13994 vos_mem_copy(pWextState->req_bssId, bssid_hint,
13995 WNI_CFG_BSSID_LEN);
13996 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
13997 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070013998 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013999
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014000
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014001 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
14002 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014003 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
14004 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014005 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014006 /*set gen ie*/
14007 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
14008 /*set auth*/
14009 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
14010 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014011#ifdef FEATURE_WLAN_WAPI
14012 if (pAdapter->wapi_info.nWapiMode)
14013 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014014 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014015 switch (pAdapter->wapi_info.wapiAuthMode)
14016 {
14017 case WAPI_AUTH_MODE_PSK:
14018 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014019 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014020 pAdapter->wapi_info.wapiAuthMode);
14021 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
14022 break;
14023 }
14024 case WAPI_AUTH_MODE_CERT:
14025 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014026 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014027 pAdapter->wapi_info.wapiAuthMode);
14028 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
14029 break;
14030 }
14031 } // End of switch
14032 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
14033 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
14034 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014035 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014036 pRoamProfile->AuthType.numEntries = 1;
14037 pRoamProfile->EncryptionType.numEntries = 1;
14038 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14039 pRoamProfile->mcEncryptionType.numEntries = 1;
14040 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14041 }
14042 }
14043#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014044#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014045 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014046 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14047 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
14048 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014049 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
14050 sizeof (tSirGtkOffloadParams));
14051 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014052 }
14053#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014054 pRoamProfile->csrPersona = pAdapter->device_mode;
14055
Jeff Johnson32d95a32012-09-10 13:15:23 -070014056 if( operatingChannel )
14057 {
14058 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
14059 pRoamProfile->ChannelInfo.numOfChannels = 1;
14060 }
Chet Lanctot186b5732013-03-18 10:26:30 -070014061 else
14062 {
14063 pRoamProfile->ChannelInfo.ChannelList = NULL;
14064 pRoamProfile->ChannelInfo.numOfChannels = 0;
14065 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014066 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
14067 {
14068 hdd_select_cbmode(pAdapter,operatingChannel);
14069 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014070
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014071 /*
14072 * Change conn_state to connecting before sme_RoamConnect(),
14073 * because sme_RoamConnect() has a direct path to call
14074 * hdd_smeRoamCallback(), which will change the conn_state
14075 * If direct path, conn_state will be accordingly changed
14076 * to NotConnected or Associated by either
14077 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
14078 * in sme_RoamCallback()
14079 * if sme_RomConnect is to be queued,
14080 * Connecting state will remain until it is completed.
14081 * If connection state is not changed,
14082 * connection state will remain in eConnectionState_NotConnected state.
14083 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
14084 * if conn state is eConnectionState_NotConnected.
14085 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
14086 * informed of connect result indication which is an issue.
14087 */
14088
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014089 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14090 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053014091 {
14092 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014093 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014094 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
14095 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053014096 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014097 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014098 pAdapter->sessionId, pRoamProfile, &roamId);
14099
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014100 if ((eHAL_STATUS_SUCCESS != status) &&
14101 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14102 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014103
14104 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014105 hddLog(VOS_TRACE_LEVEL_ERROR,
14106 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
14107 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014108 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014109 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014110 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014111 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014112
14113 pRoamProfile->ChannelInfo.ChannelList = NULL;
14114 pRoamProfile->ChannelInfo.numOfChannels = 0;
14115
Jeff Johnson295189b2012-06-20 16:38:30 -070014116 }
14117 else
14118 {
14119 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
14120 return -EINVAL;
14121 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080014122 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014123 return status;
14124}
14125
14126/*
14127 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
14128 * This function is used to set the authentication type (OPEN/SHARED).
14129 *
14130 */
14131static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
14132 enum nl80211_auth_type auth_type)
14133{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014134 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014135 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14136
14137 ENTER();
14138
14139 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014140 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070014141 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014142 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014143 hddLog(VOS_TRACE_LEVEL_INFO,
14144 "%s: set authentication type to AUTOSWITCH", __func__);
14145 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
14146 break;
14147
14148 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014149#ifdef WLAN_FEATURE_VOWIFI_11R
14150 case NL80211_AUTHTYPE_FT:
14151#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014152 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014153 "%s: set authentication type to OPEN", __func__);
14154 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
14155 break;
14156
14157 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014158 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014159 "%s: set authentication type to SHARED", __func__);
14160 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
14161 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014162#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014163 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014164 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014165 "%s: set authentication type to CCKM WPA", __func__);
14166 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
14167 break;
14168#endif
14169
14170
14171 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014172 hddLog(VOS_TRACE_LEVEL_ERROR,
14173 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014174 auth_type);
14175 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
14176 return -EINVAL;
14177 }
14178
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014179 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014180 pHddStaCtx->conn_info.authType;
14181 return 0;
14182}
14183
14184/*
14185 * FUNCTION: wlan_hdd_set_akm_suite
14186 * This function is used to set the key mgmt type(PSK/8021x).
14187 *
14188 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014189static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014190 u32 key_mgmt
14191 )
14192{
14193 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14194 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053014195 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014196#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053014197#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014198#endif
14199#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053014200#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014201#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014202 /*set key mgmt type*/
14203 switch(key_mgmt)
14204 {
14205 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053014206 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014207#ifdef WLAN_FEATURE_VOWIFI_11R
14208 case WLAN_AKM_SUITE_FT_PSK:
14209#endif
14210 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070014211 __func__);
14212 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
14213 break;
14214
14215 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053014216 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014217#ifdef WLAN_FEATURE_VOWIFI_11R
14218 case WLAN_AKM_SUITE_FT_8021X:
14219#endif
14220 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070014221 __func__);
14222 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14223 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014224#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014225#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
14226#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
14227 case WLAN_AKM_SUITE_CCKM:
14228 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
14229 __func__);
14230 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
14231 break;
14232#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070014233#ifndef WLAN_AKM_SUITE_OSEN
14234#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
14235 case WLAN_AKM_SUITE_OSEN:
14236 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
14237 __func__);
14238 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14239 break;
14240#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014241
14242 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014243 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014244 __func__, key_mgmt);
14245 return -EINVAL;
14246
14247 }
14248 return 0;
14249}
14250
14251/*
14252 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014253 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070014254 * (NONE/WEP40/WEP104/TKIP/CCMP).
14255 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014256static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
14257 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070014258 bool ucast
14259 )
14260{
14261 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014262 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014263 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14264
14265 ENTER();
14266
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014267 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014268 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014269 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070014270 __func__, cipher);
14271 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14272 }
14273 else
14274 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014275
Jeff Johnson295189b2012-06-20 16:38:30 -070014276 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014277 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014278 {
14279 case IW_AUTH_CIPHER_NONE:
14280 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14281 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014282
Jeff Johnson295189b2012-06-20 16:38:30 -070014283 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014284 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070014285 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014286
Jeff Johnson295189b2012-06-20 16:38:30 -070014287 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014288 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070014289 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014290
Jeff Johnson295189b2012-06-20 16:38:30 -070014291 case WLAN_CIPHER_SUITE_TKIP:
14292 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
14293 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014294
Jeff Johnson295189b2012-06-20 16:38:30 -070014295 case WLAN_CIPHER_SUITE_CCMP:
14296 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14297 break;
14298#ifdef FEATURE_WLAN_WAPI
14299 case WLAN_CIPHER_SUITE_SMS4:
14300 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
14301 break;
14302#endif
14303
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014304#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014305 case WLAN_CIPHER_SUITE_KRK:
14306 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
14307 break;
14308#endif
14309 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014310 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014311 __func__, cipher);
14312 return -EOPNOTSUPP;
14313 }
14314 }
14315
14316 if (ucast)
14317 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014318 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014319 __func__, encryptionType);
14320 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14321 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014322 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014323 encryptionType;
14324 }
14325 else
14326 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014327 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014328 __func__, encryptionType);
14329 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
14330 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
14331 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
14332 }
14333
14334 return 0;
14335}
14336
14337
14338/*
14339 * FUNCTION: wlan_hdd_cfg80211_set_ie
14340 * This function is used to parse WPA/RSN IE's.
14341 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014342int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014343#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14344 const u8 *ie,
14345#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014346 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014347#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014348 size_t ie_len
14349 )
14350{
14351 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014352#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14353 const u8 *genie = ie;
14354#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014355 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014356#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014357 v_U16_t remLen = ie_len;
14358#ifdef FEATURE_WLAN_WAPI
14359 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
14360 u16 *tmp;
14361 v_U16_t akmsuiteCount;
14362 int *akmlist;
14363#endif
14364 ENTER();
14365
14366 /* clear previous assocAddIE */
14367 pWextState->assocAddIE.length = 0;
14368 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014369 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014370
14371 while (remLen >= 2)
14372 {
14373 v_U16_t eLen = 0;
14374 v_U8_t elementId;
14375 elementId = *genie++;
14376 eLen = *genie++;
14377 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014378
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053014379 /* Sanity check on eLen */
14380 if (eLen > remLen) {
14381 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
14382 __func__, eLen, elementId);
14383 VOS_ASSERT(0);
14384 return -EINVAL;
14385 }
14386
Arif Hussain6d2a3322013-11-17 19:50:10 -080014387 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070014388 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014389
14390 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070014391 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014392 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014393 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 -070014394 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014395 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014396 "%s: Invalid WPA IE", __func__);
14397 return -EINVAL;
14398 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014399 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070014400 {
14401 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014402 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014403 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014404
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014405 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014406 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014407 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
14408 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014409 VOS_ASSERT(0);
14410 return -ENOMEM;
14411 }
14412 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14413 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14414 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014415
Jeff Johnson295189b2012-06-20 16:38:30 -070014416 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
14417 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14418 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14419 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014420 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
14421 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053014422 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
14423 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
14424 __func__, eLen);
14425 VOS_ASSERT(0);
14426 return -EINVAL;
14427 }
14428
Jeff Johnson295189b2012-06-20 16:38:30 -070014429 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
14430 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14431 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
14432 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
14433 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
14434 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014435 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053014436 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070014437 {
14438 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014439 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014440 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014441
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014442 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014443 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014444 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14445 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014446 VOS_ASSERT(0);
14447 return -ENOMEM;
14448 }
14449 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14450 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14451 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014452
Jeff Johnson295189b2012-06-20 16:38:30 -070014453 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14454 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14455 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014456#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014457 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
14458 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014459 /*Consider WFD IE, only for P2P Client */
14460 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
14461 {
14462 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014463 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014464 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014465
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014466 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014467 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014468 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14469 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014470 VOS_ASSERT(0);
14471 return -ENOMEM;
14472 }
14473 // WFD IE is saved to Additional IE ; it should be accumulated to handle
14474 // WPS IE + P2P IE + WFD IE
14475 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14476 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014477
Jeff Johnson295189b2012-06-20 16:38:30 -070014478 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14479 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14480 }
14481#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014482 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014483 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014484 HS20_OUI_TYPE_SIZE)) )
14485 {
14486 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014487 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014488 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014489
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014490 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014491 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014492 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14493 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014494 VOS_ASSERT(0);
14495 return -ENOMEM;
14496 }
14497 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14498 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014499
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014500 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14501 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14502 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014503 /* Appending OSEN Information Element in Assiciation Request */
14504 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
14505 OSEN_OUI_TYPE_SIZE)) )
14506 {
14507 v_U16_t curAddIELen = pWextState->assocAddIE.length;
14508 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
14509 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014510
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014511 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014512 {
14513 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14514 "Need bigger buffer space");
14515 VOS_ASSERT(0);
14516 return -ENOMEM;
14517 }
14518 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14519 pWextState->assocAddIE.length += eLen + 2;
14520
14521 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
14522 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14523 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14524 }
14525
Abhishek Singh4322e622015-06-10 15:42:54 +053014526 /* Update only for WPA IE */
14527 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
14528 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014529
14530 /* populating as ADDIE in beacon frames */
14531 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014532 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014533 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
14534 {
14535 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14536 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
14537 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14538 {
14539 hddLog(LOGE,
14540 "Coldn't pass "
14541 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
14542 }
14543 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
14544 else
14545 hddLog(LOGE,
14546 "Could not pass on "
14547 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
14548
14549 /* IBSS mode doesn't contain params->proberesp_ies still
14550 beaconIE's need to be populated in probe response frames */
14551 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
14552 {
14553 u16 rem_probe_resp_ie_len = eLen + 2;
14554 u8 probe_rsp_ie_len[3] = {0};
14555 u8 counter = 0;
14556
14557 /* Check Probe Resp Length if it is greater then 255 then
14558 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
14559 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
14560 not able Store More then 255 bytes into One Variable */
14561
14562 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
14563 {
14564 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
14565 {
14566 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
14567 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
14568 }
14569 else
14570 {
14571 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
14572 rem_probe_resp_ie_len = 0;
14573 }
14574 }
14575
14576 rem_probe_resp_ie_len = 0;
14577
14578 if (probe_rsp_ie_len[0] > 0)
14579 {
14580 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14581 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
14582 (tANI_U8*)(genie - 2),
14583 probe_rsp_ie_len[0], NULL,
14584 eANI_BOOLEAN_FALSE)
14585 == eHAL_STATUS_FAILURE)
14586 {
14587 hddLog(LOGE,
14588 "Could not pass"
14589 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
14590 }
14591 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
14592 }
14593
14594 if (probe_rsp_ie_len[1] > 0)
14595 {
14596 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14597 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
14598 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14599 probe_rsp_ie_len[1], NULL,
14600 eANI_BOOLEAN_FALSE)
14601 == eHAL_STATUS_FAILURE)
14602 {
14603 hddLog(LOGE,
14604 "Could not pass"
14605 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
14606 }
14607 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
14608 }
14609
14610 if (probe_rsp_ie_len[2] > 0)
14611 {
14612 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14613 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
14614 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14615 probe_rsp_ie_len[2], NULL,
14616 eANI_BOOLEAN_FALSE)
14617 == eHAL_STATUS_FAILURE)
14618 {
14619 hddLog(LOGE,
14620 "Could not pass"
14621 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
14622 }
14623 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
14624 }
14625
14626 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14627 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
14628 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14629 {
14630 hddLog(LOGE,
14631 "Could not pass"
14632 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
14633 }
14634 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014635 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014636 break;
14637 case DOT11F_EID_RSN:
14638 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
14639 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14640 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
14641 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
14642 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
14643 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053014644
Abhishek Singhb16f3562016-01-20 11:08:32 +053014645 /* Appending extended capabilities with Interworking or
14646 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053014647 *
14648 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053014649 * interworkingService or bsstransition bit is set to 1.
14650 * Driver is only interested in interworkingService and
14651 * bsstransition capability from supplicant.
14652 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053014653 * required from supplicat, it needs to be handled while
14654 * sending Assoc Req in LIM.
14655 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014656 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014657 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014658 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014659 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014660 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014661
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014662 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014663 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014664 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14665 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014666 VOS_ASSERT(0);
14667 return -ENOMEM;
14668 }
14669 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14670 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014671
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014672 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14673 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14674 break;
14675 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014676#ifdef FEATURE_WLAN_WAPI
14677 case WLAN_EID_WAPI:
14678 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014679 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014680 pAdapter->wapi_info.nWapiMode);
14681 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014682 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014683 akmsuiteCount = WPA_GET_LE16(tmp);
14684 tmp = tmp + 1;
14685 akmlist = (int *)(tmp);
14686 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14687 {
14688 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14689 }
14690 else
14691 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014692 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014693 VOS_ASSERT(0);
14694 return -EINVAL;
14695 }
14696
14697 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14698 {
14699 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014700 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014701 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014702 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014703 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014704 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014705 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014706 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014707 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14708 }
14709 break;
14710#endif
14711 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014712 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014713 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014714 /* when Unknown IE is received we should break and continue
14715 * to the next IE in the buffer instead we were returning
14716 * so changing this to break */
14717 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014718 }
14719 genie += eLen;
14720 remLen -= eLen;
14721 }
14722 EXIT();
14723 return 0;
14724}
14725
14726/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014727 * FUNCTION: hdd_isWPAIEPresent
14728 * Parse the received IE to find the WPA IE
14729 *
14730 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014731static bool hdd_isWPAIEPresent(
14732#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14733 const u8 *ie,
14734#else
14735 u8 *ie,
14736#endif
14737 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014738{
14739 v_U8_t eLen = 0;
14740 v_U16_t remLen = ie_len;
14741 v_U8_t elementId = 0;
14742
14743 while (remLen >= 2)
14744 {
14745 elementId = *ie++;
14746 eLen = *ie++;
14747 remLen -= 2;
14748 if (eLen > remLen)
14749 {
14750 hddLog(VOS_TRACE_LEVEL_ERROR,
14751 "%s: IE length is wrong %d", __func__, eLen);
14752 return FALSE;
14753 }
14754 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14755 {
14756 /* OUI - 0x00 0X50 0XF2
14757 WPA Information Element - 0x01
14758 WPA version - 0x01*/
14759 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14760 return TRUE;
14761 }
14762 ie += eLen;
14763 remLen -= eLen;
14764 }
14765 return FALSE;
14766}
14767
14768/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014769 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014770 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014771 * parameters during connect operation.
14772 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014773int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014774 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014775 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014776{
14777 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014778 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014779 ENTER();
14780
14781 /*set wpa version*/
14782 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14783
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014784 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014785 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014786 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014787 {
14788 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14789 }
14790 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14791 {
14792 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14793 }
14794 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014795
14796 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014797 pWextState->wpaVersion);
14798
14799 /*set authentication type*/
14800 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14801
14802 if (0 > status)
14803 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014804 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014805 "%s: failed to set authentication type ", __func__);
14806 return status;
14807 }
14808
14809 /*set key mgmt type*/
14810 if (req->crypto.n_akm_suites)
14811 {
14812 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14813 if (0 > status)
14814 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014815 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014816 __func__);
14817 return status;
14818 }
14819 }
14820
14821 /*set pairwise cipher type*/
14822 if (req->crypto.n_ciphers_pairwise)
14823 {
14824 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14825 req->crypto.ciphers_pairwise[0], true);
14826 if (0 > status)
14827 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014828 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014829 "%s: failed to set unicast cipher type", __func__);
14830 return status;
14831 }
14832 }
14833 else
14834 {
14835 /*Reset previous cipher suite to none*/
14836 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14837 if (0 > status)
14838 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014839 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014840 "%s: failed to set unicast cipher type", __func__);
14841 return status;
14842 }
14843 }
14844
14845 /*set group cipher type*/
14846 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14847 false);
14848
14849 if (0 > status)
14850 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014851 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014852 __func__);
14853 return status;
14854 }
14855
Chet Lanctot186b5732013-03-18 10:26:30 -070014856#ifdef WLAN_FEATURE_11W
14857 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14858#endif
14859
Jeff Johnson295189b2012-06-20 16:38:30 -070014860 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14861 if (req->ie_len)
14862 {
14863 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14864 if ( 0 > status)
14865 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014866 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014867 __func__);
14868 return status;
14869 }
14870 }
14871
14872 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014873 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014874 {
14875 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14876 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14877 )
14878 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014879 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014880 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14881 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014882 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014883 __func__);
14884 return -EOPNOTSUPP;
14885 }
14886 else
14887 {
14888 u8 key_len = req->key_len;
14889 u8 key_idx = req->key_idx;
14890
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014891 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014892 && (CSR_MAX_NUM_KEY > key_idx)
14893 )
14894 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014895 hddLog(VOS_TRACE_LEVEL_INFO,
14896 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014897 __func__, key_idx, key_len);
14898 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014899 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014900 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014901 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014902 (u8)key_len;
14903 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14904 }
14905 }
14906 }
14907 }
14908
14909 return status;
14910}
14911
14912/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014913 * FUNCTION: wlan_hdd_try_disconnect
14914 * This function is used to disconnect from previous
14915 * connection
14916 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053014917int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014918{
14919 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014920 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014921 hdd_station_ctx_t *pHddStaCtx;
14922 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014923 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014924
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014925 ret = wlan_hdd_validate_context(pHddCtx);
14926 if (0 != ret)
14927 {
14928 return ret;
14929 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014930 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14931
14932 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14933
14934 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14935 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053014936 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014937 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14938 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053014939 /* Indicate disconnect to SME so that in-progress connection or preauth
14940 * can be aborted
14941 */
14942 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
14943 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014944 spin_lock_bh(&pAdapter->lock_for_active_session);
14945 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14946 {
14947 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14948 }
14949 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053014950 hdd_connSetConnectionState(pHddStaCtx,
14951 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014952 /* Issue disconnect to CSR */
14953 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014954 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014955 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014956 eCSR_DISCONNECT_REASON_UNSPECIFIED);
14957 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
14958 hddLog(LOG1,
14959 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
14960 } else if ( 0 != status ) {
14961 hddLog(LOGE,
14962 FL("csrRoamDisconnect failure, returned %d"),
14963 (int)status );
14964 result = -EINVAL;
14965 goto disconnected;
14966 }
14967 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014968 &pAdapter->disconnect_comp_var,
14969 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014970 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
14971 hddLog(LOGE,
14972 "%s: Failed to disconnect, timed out", __func__);
14973 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014974 }
14975 }
14976 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14977 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014978 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014979 &pAdapter->disconnect_comp_var,
14980 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014981 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014982 {
14983 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014984 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014985 }
14986 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014987disconnected:
14988 hddLog(LOG1,
14989 FL("Set HDD connState to eConnectionState_NotConnected"));
14990 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14991 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014992}
14993
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014994/**
14995 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
14996 * @adapter: Pointer to the HDD adapter
14997 * @req: Pointer to the structure cfg_connect_params receieved from user space
14998 *
14999 * This function will start reassociation if bssid hint, channel hint and
15000 * previous bssid parameters are present in the connect request
15001 *
15002 * Return: success if reassociation is happening
15003 * Error code if reassociation is not permitted or not happening
15004 */
15005#ifdef CFG80211_CONNECT_PREV_BSSID
15006static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15007 struct cfg80211_connect_params *req)
15008{
15009 int status = -EPERM;
15010 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
15011 hddLog(VOS_TRACE_LEVEL_INFO,
15012 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
15013 req->channel_hint->hw_value,
15014 MAC_ADDR_ARRAY(req->bssid_hint));
15015 status = hdd_reassoc(adapter, req->bssid_hint,
15016 req->channel_hint->hw_value,
15017 CONNECT_CMD_USERSPACE);
15018 }
15019 return status;
15020}
15021#else
15022static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15023 struct cfg80211_connect_params *req)
15024{
15025 return -EPERM;
15026}
15027#endif
15028
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015029/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053015030 * FUNCTION: __wlan_hdd_cfg80211_connect
15031 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015032 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015033static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015034 struct net_device *ndev,
15035 struct cfg80211_connect_params *req
15036 )
15037{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015038 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015039 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053015040#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
15041 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015042 const u8 *bssid_hint = req->bssid_hint;
15043#else
15044 const u8 *bssid_hint = NULL;
15045#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015046 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015047 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053015048 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015049
15050 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015051
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015052 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15053 TRACE_CODE_HDD_CFG80211_CONNECT,
15054 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015055 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015056 "%s: device_mode = %s (%d)", __func__,
15057 hdd_device_modetoString(pAdapter->device_mode),
15058 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015059
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015060 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015061 if (!pHddCtx)
15062 {
15063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15064 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015065 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015066 }
15067
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015068 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015069 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015070 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015071 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015072 }
15073
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015074 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
15075 if (0 == status)
15076 return status;
15077
Agarwal Ashish51325b52014-06-16 16:50:49 +053015078
Jeff Johnson295189b2012-06-20 16:38:30 -070015079#ifdef WLAN_BTAMP_FEATURE
15080 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015081 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070015082 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015083 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015084 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080015085 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070015086 }
15087#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015088
15089 //If Device Mode is Station Concurrent Sessions Exit BMps
15090 //P2P Mode will be taken care in Open/close adapter
15091 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053015092 (vos_concurrent_open_sessions_running())) {
15093 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
15094 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015095 }
15096
15097 /*Try disconnecting if already in connected state*/
15098 status = wlan_hdd_try_disconnect(pAdapter);
15099 if ( 0 > status)
15100 {
15101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15102 " connection"));
15103 return -EALREADY;
15104 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053015105 /* Check for max concurrent connections after doing disconnect if any*/
15106 if (vos_max_concurrent_connections_reached()) {
15107 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15108 return -ECONNREFUSED;
15109 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015110
Jeff Johnson295189b2012-06-20 16:38:30 -070015111 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015112 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070015113
15114 if ( 0 > status)
15115 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015116 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070015117 __func__);
15118 return status;
15119 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053015120
15121 if (pHddCtx->spoofMacAddr.isEnabled)
15122 {
15123 hddLog(VOS_TRACE_LEVEL_INFO,
15124 "%s: MAC Spoofing enabled ", __func__);
15125 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15126 * to fill TxBds for probe request during SSID scan which may happen
15127 * as part of connect command
15128 */
15129 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
15130 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
15131 if (status != VOS_STATUS_SUCCESS)
15132 return -ECONNREFUSED;
15133 }
15134
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015135 if (req->channel)
15136 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070015137 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015138 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053015139
15140 /* Abort if any scan is going on */
15141 status = wlan_hdd_scan_abort(pAdapter);
15142 if (0 != status)
15143 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
15144
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015145 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
15146 req->ssid_len, req->bssid,
15147 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015148
Sushant Kaushikd7083982015-03-18 14:33:24 +053015149 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015150 {
15151 //ReEnable BMPS if disabled
15152 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
15153 (NULL != pHddCtx))
15154 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053015155 if (pHddCtx->hdd_wlan_suspended)
15156 {
15157 hdd_set_pwrparams(pHddCtx);
15158 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015159 //ReEnable Bmps and Imps back
15160 hdd_enable_bmps_imps(pHddCtx);
15161 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015162 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070015163 return status;
15164 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015165 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015166 EXIT();
15167 return status;
15168}
15169
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015170static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
15171 struct net_device *ndev,
15172 struct cfg80211_connect_params *req)
15173{
15174 int ret;
15175 vos_ssr_protect(__func__);
15176 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
15177 vos_ssr_unprotect(__func__);
15178
15179 return ret;
15180}
Jeff Johnson295189b2012-06-20 16:38:30 -070015181
15182/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015183 * FUNCTION: wlan_hdd_disconnect
15184 * This function is used to issue a disconnect request to SME
15185 */
15186int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
15187{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015188 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015189 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015190 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015191 long ret;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015192 eConnectionState prev_conn_state;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015193
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015194 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015195
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015196 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015197 if (0 != status)
15198 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015199 return status;
15200 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053015201 /* Indicate sme of disconnect so that in progress connection or preauth
15202 * can be aborted
15203 */
15204 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053015205 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015206 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015207
Agarwal Ashish47d18112014-08-04 19:55:07 +053015208 /* Need to apply spin lock before decreasing active sessions
15209 * as there can be chance for double decrement if context switch
15210 * Calls hdd_DisConnectHandler.
15211 */
15212
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015213 prev_conn_state = pHddStaCtx->conn_info.connState;
15214
Agarwal Ashish47d18112014-08-04 19:55:07 +053015215 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015216 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15217 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015218 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15219 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053015220 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
15221 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015222
Abhishek Singhf4669da2014-05-26 15:07:49 +053015223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053015224 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
15225
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015226 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015227
Mihir Shete182a0b22014-08-18 16:08:48 +053015228 /*
15229 * stop tx queues before deleting STA/BSS context from the firmware.
15230 * tx has to be disabled because the firmware can get busy dropping
15231 * the tx frames after BSS/STA has been deleted and will not send
15232 * back a response resulting in WDI timeout
15233 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053015234 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053015235 netif_tx_disable(pAdapter->dev);
15236 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015237
Mihir Shete182a0b22014-08-18 16:08:48 +053015238 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015239 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
15240 pAdapter->sessionId, reason);
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015241 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
15242 prev_conn_state != eConnectionState_Connecting)
15243 {
15244 hddLog(LOG1,
15245 FL("status = %d, already disconnected"), status);
15246 result = 0;
15247 goto disconnected;
15248 }
15249 /*
15250 * Wait here instead of returning directly, this will block the next
15251 * connect command and allow processing of the scan for ssid and
15252 * the previous connect command in CSR. Else we might hit some
15253 * race conditions leading to SME and HDD out of sync.
15254 */
15255 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015256 {
15257 hddLog(LOG1,
15258 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015259 }
15260 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015261 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015262 hddLog(LOGE,
15263 FL("csrRoamDisconnect failure, returned %d"),
15264 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015265 result = -EINVAL;
15266 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015267 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015268 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015269 &pAdapter->disconnect_comp_var,
15270 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015271 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015272 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015273 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015274 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015275 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015276 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015277disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015278 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015279 FL("Set HDD connState to eConnectionState_NotConnected"));
15280 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015281#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
15282 /* Sending disconnect event to userspace for kernel version < 3.11
15283 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
15284 */
15285 hddLog(LOG1, FL("Send disconnected event to userspace"));
15286
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053015287 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015288 WLAN_REASON_UNSPECIFIED);
15289#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015290
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015291 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015292 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015293}
15294
15295
15296/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015297 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070015298 * This function is used to issue a disconnect request to SME
15299 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015300static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015301 struct net_device *dev,
15302 u16 reason
15303 )
15304{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015305 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015306 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015307 tCsrRoamProfile *pRoamProfile;
15308 hdd_station_ctx_t *pHddStaCtx;
15309 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015310#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015311 tANI_U8 staIdx;
15312#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015313
Jeff Johnson295189b2012-06-20 16:38:30 -070015314 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015315
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015316 if (!pAdapter) {
15317 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15318 return -EINVAL;
15319 }
15320
15321 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15322 if (!pHddStaCtx) {
15323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
15324 return -EINVAL;
15325 }
15326
15327 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15328 status = wlan_hdd_validate_context(pHddCtx);
15329 if (0 != status)
15330 {
15331 return status;
15332 }
15333
15334 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
15335
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015336 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15337 TRACE_CODE_HDD_CFG80211_DISCONNECT,
15338 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015339 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
15340 __func__, hdd_device_modetoString(pAdapter->device_mode),
15341 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015342
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015343 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
15344 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070015345
Jeff Johnson295189b2012-06-20 16:38:30 -070015346 if (NULL != pRoamProfile)
15347 {
15348 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015349 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
15350 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070015351 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015352 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070015353 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015354 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070015355 switch(reason)
15356 {
15357 case WLAN_REASON_MIC_FAILURE:
15358 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
15359 break;
15360
15361 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
15362 case WLAN_REASON_DISASSOC_AP_BUSY:
15363 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
15364 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
15365 break;
15366
15367 case WLAN_REASON_PREV_AUTH_NOT_VALID:
15368 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053015369 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070015370 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
15371 break;
15372
Jeff Johnson295189b2012-06-20 16:38:30 -070015373 default:
15374 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
15375 break;
15376 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015377 pScanInfo = &pHddCtx->scan_info;
15378 if (pScanInfo->mScanPending)
15379 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015380 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015381 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015382 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015383 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015384 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053015385 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015386#ifdef FEATURE_WLAN_TDLS
15387 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015388 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015389 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015390 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
15391 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015392 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015393 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015394 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015395 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015396 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015397 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015398 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015399 status = sme_DeleteTdlsPeerSta(
15400 WLAN_HDD_GET_HAL_CTX(pAdapter),
15401 pAdapter->sessionId,
15402 mac);
15403 if (status != eHAL_STATUS_SUCCESS) {
15404 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15405 return -EPERM;
15406 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015407 }
15408 }
15409#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015410
15411 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
15412 reasonCode,
15413 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015414 status = wlan_hdd_disconnect(pAdapter, reasonCode);
15415 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070015416 {
15417 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015418 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015419 __func__, (int)status );
15420 return -EINVAL;
15421 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015422 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015423 else
15424 {
15425 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
15426 "called while in %d state", __func__,
15427 pHddStaCtx->conn_info.connState);
15428 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015429 }
15430 else
15431 {
15432 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
15433 }
15434
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015435 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015436 return status;
15437}
15438
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015439static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
15440 struct net_device *dev,
15441 u16 reason
15442 )
15443{
15444 int ret;
15445 vos_ssr_protect(__func__);
15446 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
15447 vos_ssr_unprotect(__func__);
15448
15449 return ret;
15450}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015451
Jeff Johnson295189b2012-06-20 16:38:30 -070015452/*
15453 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015454 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015455 * settings in IBSS mode.
15456 */
15457static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015458 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015459 struct cfg80211_ibss_params *params
15460 )
15461{
15462 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015463 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015464 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15465 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015466
Jeff Johnson295189b2012-06-20 16:38:30 -070015467 ENTER();
15468
15469 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070015470 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070015471
15472 if (params->ie_len && ( NULL != params->ie) )
15473 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015474 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15475 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015476 {
15477 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15478 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15479 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015480 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015481 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015482 tDot11fIEWPA dot11WPAIE;
15483 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015484 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015485
Wilson Yang00256342013-10-10 23:13:38 -070015486 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015487 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15488 params->ie_len, DOT11F_EID_WPA);
15489 if ( NULL != ie )
15490 {
15491 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15492 // Unpack the WPA IE
15493 //Skip past the EID byte and length byte - and four byte WiFi OUI
15494 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
15495 &ie[2+4],
15496 ie[1] - 4,
15497 &dot11WPAIE);
15498 /*Extract the multicast cipher, the encType for unicast
15499 cipher for wpa-none is none*/
15500 encryptionType =
15501 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
15502 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015503 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015504
Jeff Johnson295189b2012-06-20 16:38:30 -070015505 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
15506
15507 if (0 > status)
15508 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015509 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015510 __func__);
15511 return status;
15512 }
15513 }
15514
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015515 pWextState->roamProfile.AuthType.authType[0] =
15516 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070015517 eCSR_AUTH_TYPE_OPEN_SYSTEM;
15518
15519 if (params->privacy)
15520 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015521 /* Security enabled IBSS, At this time there is no information available
15522 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070015523 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015524 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070015525 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015526 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070015527 *enable privacy bit in beacons */
15528
15529 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
15530 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015531 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
15532 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070015533 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15534 pWextState->roamProfile.EncryptionType.numEntries = 1;
15535 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070015536 return status;
15537}
15538
15539/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015540 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015541 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015542 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015543static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015544 struct net_device *dev,
15545 struct cfg80211_ibss_params *params
15546 )
15547{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015548 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015549 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15550 tCsrRoamProfile *pRoamProfile;
15551 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015552 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15553 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015554 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070015555
15556 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015557
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015558 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15559 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
15560 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015561 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015562 "%s: device_mode = %s (%d)", __func__,
15563 hdd_device_modetoString(pAdapter->device_mode),
15564 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015565
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015566 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015567 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015568 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015569 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015570 }
15571
15572 if (NULL == pWextState)
15573 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015574 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015575 __func__);
15576 return -EIO;
15577 }
15578
Agarwal Ashish51325b52014-06-16 16:50:49 +053015579 if (vos_max_concurrent_connections_reached()) {
15580 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15581 return -ECONNREFUSED;
15582 }
15583
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015584 /*Try disconnecting if already in connected state*/
15585 status = wlan_hdd_try_disconnect(pAdapter);
15586 if ( 0 > status)
15587 {
15588 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15589 " IBSS connection"));
15590 return -EALREADY;
15591 }
15592
Jeff Johnson295189b2012-06-20 16:38:30 -070015593 pRoamProfile = &pWextState->roamProfile;
15594
15595 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
15596 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015597 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015598 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015599 return -EINVAL;
15600 }
15601
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015602 /* BSSID is provided by upper layers hence no need to AUTO generate */
15603 if (NULL != params->bssid) {
15604 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15605 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
15606 hddLog (VOS_TRACE_LEVEL_ERROR,
15607 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15608 return -EIO;
15609 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015610 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015611 }
krunal sonie9002db2013-11-25 14:24:17 -080015612 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
15613 {
15614 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15615 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
15616 {
15617 hddLog (VOS_TRACE_LEVEL_ERROR,
15618 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15619 return -EIO;
15620 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015621
15622 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080015623 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015624 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080015625 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015626
Jeff Johnson295189b2012-06-20 16:38:30 -070015627 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070015628 if (NULL !=
15629#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15630 params->chandef.chan)
15631#else
15632 params->channel)
15633#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015634 {
15635 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015636 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15637 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
15638 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15639 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015640
15641 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015642 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070015643 ieee80211_frequency_to_channel(
15644#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15645 params->chandef.chan->center_freq);
15646#else
15647 params->channel->center_freq);
15648#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015649
15650 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15651 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070015652 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015653 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
15654 __func__);
15655 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070015656 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015657
15658 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015659 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015660 if (channelNum == validChan[indx])
15661 {
15662 break;
15663 }
15664 }
15665 if (indx >= numChans)
15666 {
15667 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015668 __func__, channelNum);
15669 return -EINVAL;
15670 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015671 /* Set the Operational Channel */
15672 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
15673 channelNum);
15674 pRoamProfile->ChannelInfo.numOfChannels = 1;
15675 pHddStaCtx->conn_info.operationChannel = channelNum;
15676 pRoamProfile->ChannelInfo.ChannelList =
15677 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070015678 }
15679
15680 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015681 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070015682 if (status < 0)
15683 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015684 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070015685 __func__);
15686 return status;
15687 }
15688
15689 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015690 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053015691 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015692 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015693
15694 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015696
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015697 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015698 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015699}
15700
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015701static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
15702 struct net_device *dev,
15703 struct cfg80211_ibss_params *params
15704 )
15705{
15706 int ret = 0;
15707
15708 vos_ssr_protect(__func__);
15709 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
15710 vos_ssr_unprotect(__func__);
15711
15712 return ret;
15713}
15714
Jeff Johnson295189b2012-06-20 16:38:30 -070015715/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015716 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015717 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015718 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015719static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015720 struct net_device *dev
15721 )
15722{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015723 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015724 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15725 tCsrRoamProfile *pRoamProfile;
15726 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015727 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053015728 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015729#ifdef WLAN_FEATURE_RMC
15730 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
15731#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015732
15733 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015734
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015735 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15736 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
15737 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015738 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015739 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015740 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015741 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015742 }
15743
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015744 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
15745 hdd_device_modetoString(pAdapter->device_mode),
15746 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015747 if (NULL == pWextState)
15748 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015749 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015750 __func__);
15751 return -EIO;
15752 }
15753
15754 pRoamProfile = &pWextState->roamProfile;
15755
15756 /* Issue disconnect only if interface type is set to IBSS */
15757 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
15758 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015759 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070015760 __func__);
15761 return -EINVAL;
15762 }
15763
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015764#ifdef WLAN_FEATURE_RMC
15765 /* Clearing add IE of beacon */
15766 if (ccmCfgSetStr(pHddCtx->hHal,
15767 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
15768 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
15769 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15770 {
15771 hddLog (VOS_TRACE_LEVEL_ERROR,
15772 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
15773 return -EINVAL;
15774 }
15775 if (ccmCfgSetInt(pHddCtx->hHal,
15776 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
15777 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15778 {
15779 hddLog (VOS_TRACE_LEVEL_ERROR,
15780 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
15781 __func__);
15782 return -EINVAL;
15783 }
15784
15785 // Reset WNI_CFG_PROBE_RSP Flags
15786 wlan_hdd_reset_prob_rspies(pAdapter);
15787
15788 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15789 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
15790 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15791 {
15792 hddLog (VOS_TRACE_LEVEL_ERROR,
15793 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
15794 __func__);
15795 return -EINVAL;
15796 }
15797#endif
15798
Jeff Johnson295189b2012-06-20 16:38:30 -070015799 /* Issue Disconnect request */
15800 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053015801 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
15802 pAdapter->sessionId,
15803 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
15804 if (!HAL_STATUS_SUCCESS(hal_status)) {
15805 hddLog(LOGE,
15806 FL("sme_RoamDisconnect failed hal_status(%d)"),
15807 hal_status);
15808 return -EAGAIN;
15809 }
15810 status = wait_for_completion_timeout(
15811 &pAdapter->disconnect_comp_var,
15812 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
15813 if (!status) {
15814 hddLog(LOGE,
15815 FL("wait on disconnect_comp_var failed"));
15816 return -ETIMEDOUT;
15817 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015818
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015819 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015820 return 0;
15821}
15822
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015823static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15824 struct net_device *dev
15825 )
15826{
15827 int ret = 0;
15828
15829 vos_ssr_protect(__func__);
15830 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15831 vos_ssr_unprotect(__func__);
15832
15833 return ret;
15834}
15835
Jeff Johnson295189b2012-06-20 16:38:30 -070015836/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015837 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015838 * This function is used to set the phy parameters
15839 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15840 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015841static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015842 u32 changed)
15843{
15844 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15845 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015846 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015847
15848 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015849
15850 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015851 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15852 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015853
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015854 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015855 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015856 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015857 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015858 }
15859
Jeff Johnson295189b2012-06-20 16:38:30 -070015860 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15861 {
15862 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15863 WNI_CFG_RTS_THRESHOLD_STAMAX :
15864 wiphy->rts_threshold;
15865
15866 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015867 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015868 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015869 hddLog(VOS_TRACE_LEVEL_ERROR,
15870 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015871 __func__, rts_threshold);
15872 return -EINVAL;
15873 }
15874
15875 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15876 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015877 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015878 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015879 hddLog(VOS_TRACE_LEVEL_ERROR,
15880 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015881 __func__, rts_threshold);
15882 return -EIO;
15883 }
15884
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015885 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015886 rts_threshold);
15887 }
15888
15889 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15890 {
15891 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15892 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15893 wiphy->frag_threshold;
15894
15895 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015896 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015897 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015898 hddLog(VOS_TRACE_LEVEL_ERROR,
15899 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015900 frag_threshold);
15901 return -EINVAL;
15902 }
15903
15904 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15905 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015906 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015907 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015908 hddLog(VOS_TRACE_LEVEL_ERROR,
15909 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015910 __func__, frag_threshold);
15911 return -EIO;
15912 }
15913
15914 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15915 frag_threshold);
15916 }
15917
15918 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15919 || (changed & WIPHY_PARAM_RETRY_LONG))
15920 {
15921 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15922 wiphy->retry_short :
15923 wiphy->retry_long;
15924
15925 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15926 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15927 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015928 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015929 __func__, retry_value);
15930 return -EINVAL;
15931 }
15932
15933 if (changed & WIPHY_PARAM_RETRY_SHORT)
15934 {
15935 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15936 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015937 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015938 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015939 hddLog(VOS_TRACE_LEVEL_ERROR,
15940 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015941 __func__, retry_value);
15942 return -EIO;
15943 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015944 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015945 __func__, retry_value);
15946 }
15947 else if (changed & WIPHY_PARAM_RETRY_SHORT)
15948 {
15949 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
15950 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015951 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015952 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015953 hddLog(VOS_TRACE_LEVEL_ERROR,
15954 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015955 __func__, retry_value);
15956 return -EIO;
15957 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015958 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015959 __func__, retry_value);
15960 }
15961 }
15962
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015963 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015964 return 0;
15965}
15966
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015967static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
15968 u32 changed)
15969{
15970 int ret;
15971
15972 vos_ssr_protect(__func__);
15973 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
15974 vos_ssr_unprotect(__func__);
15975
15976 return ret;
15977}
15978
Jeff Johnson295189b2012-06-20 16:38:30 -070015979/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015980 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015981 * This function is used to set the txpower
15982 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015983static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015984#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15985 struct wireless_dev *wdev,
15986#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015987#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015988 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015989#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015990 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015991#endif
15992 int dbm)
15993{
15994 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015995 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015996 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
15997 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015998 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015999
16000 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016001
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016002 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16003 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
16004 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016005 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016006 if (0 != status)
16007 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016008 return status;
16009 }
16010
16011 hHal = pHddCtx->hHal;
16012
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016013 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
16014 dbm, ccmCfgSetCallback,
16015 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016016 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016017 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016018 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
16019 return -EIO;
16020 }
16021
16022 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
16023 dbm);
16024
16025 switch(type)
16026 {
16027 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
16028 /* Fall through */
16029 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
16030 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
16031 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016032 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
16033 __func__);
16034 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070016035 }
16036 break;
16037 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016038 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016039 __func__);
16040 return -EOPNOTSUPP;
16041 break;
16042 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016043 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
16044 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070016045 return -EIO;
16046 }
16047
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016048 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016049 return 0;
16050}
16051
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016052static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
16053#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16054 struct wireless_dev *wdev,
16055#endif
16056#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16057 enum tx_power_setting type,
16058#else
16059 enum nl80211_tx_power_setting type,
16060#endif
16061 int dbm)
16062{
16063 int ret;
16064 vos_ssr_protect(__func__);
16065 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
16066#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16067 wdev,
16068#endif
16069#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16070 type,
16071#else
16072 type,
16073#endif
16074 dbm);
16075 vos_ssr_unprotect(__func__);
16076
16077 return ret;
16078}
16079
Jeff Johnson295189b2012-06-20 16:38:30 -070016080/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016081 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070016082 * This function is used to read the txpower
16083 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016084static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070016085#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16086 struct wireless_dev *wdev,
16087#endif
16088 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070016089{
16090
16091 hdd_adapter_t *pAdapter;
16092 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016093 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016094
Jeff Johnsone7245742012-09-05 17:12:55 -070016095 ENTER();
16096
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016097 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016098 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016099 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016100 *dbm = 0;
16101 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016102 }
16103
Jeff Johnson295189b2012-06-20 16:38:30 -070016104 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
16105 if (NULL == pAdapter)
16106 {
16107 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
16108 return -ENOENT;
16109 }
16110
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016111 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16112 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
16113 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070016114 wlan_hdd_get_classAstats(pAdapter);
16115 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
16116
Jeff Johnsone7245742012-09-05 17:12:55 -070016117 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016118 return 0;
16119}
16120
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016121static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
16122#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16123 struct wireless_dev *wdev,
16124#endif
16125 int *dbm)
16126{
16127 int ret;
16128
16129 vos_ssr_protect(__func__);
16130 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
16131#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16132 wdev,
16133#endif
16134 dbm);
16135 vos_ssr_unprotect(__func__);
16136
16137 return ret;
16138}
16139
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016140static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016141#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16142 const u8* mac,
16143#else
16144 u8* mac,
16145#endif
16146 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070016147{
16148 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
16149 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16150 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053016151 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016152
16153 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
16154 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070016155
16156 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
16157 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
16158 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
16159 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
16160 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
16161 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
16162 tANI_U16 maxRate = 0;
16163 tANI_U16 myRate;
16164 tANI_U16 currentRate = 0;
16165 tANI_U8 maxSpeedMCS = 0;
16166 tANI_U8 maxMCSIdx = 0;
16167 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053016168 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070016169 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016170 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016171
Leo Chang6f8870f2013-03-26 18:11:36 -070016172#ifdef WLAN_FEATURE_11AC
16173 tANI_U32 vht_mcs_map;
16174 eDataRate11ACMaxMcs vhtMaxMcs;
16175#endif /* WLAN_FEATURE_11AC */
16176
Jeff Johnsone7245742012-09-05 17:12:55 -070016177 ENTER();
16178
Jeff Johnson295189b2012-06-20 16:38:30 -070016179 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
16180 (0 == ssidlen))
16181 {
16182 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
16183 " Invalid ssidlen, %d", __func__, ssidlen);
16184 /*To keep GUI happy*/
16185 return 0;
16186 }
16187
Mukul Sharma811205f2014-07-09 21:07:30 +053016188 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16189 {
16190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16191 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053016192 /* return a cached value */
16193 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053016194 return 0;
16195 }
16196
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016197 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016198 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016199 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016200 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016201 }
16202
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053016203 wlan_hdd_get_station_stats(pAdapter);
16204 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016205
Kiet Lam3b17fc82013-09-27 05:24:08 +053016206 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
16207 sinfo->filled |= STATION_INFO_SIGNAL;
16208
c_hpothu09f19542014-05-30 21:53:31 +053016209 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053016210 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
16211 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053016212 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053016213 {
16214 rate_flags = pAdapter->maxRateFlags;
16215 }
c_hpothu44ff4e02014-05-08 00:13:57 +053016216
Jeff Johnson295189b2012-06-20 16:38:30 -070016217 //convert to the UI units of 100kbps
16218 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
16219
16220#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070016221 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 -070016222 sinfo->signal,
16223 pCfg->reportMaxLinkSpeed,
16224 myRate,
16225 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016226 (int) pCfg->linkSpeedRssiMid,
16227 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070016228 (int) rate_flags,
16229 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070016230#endif //LINKSPEED_DEBUG_ENABLED
16231
16232 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
16233 {
16234 // we do not want to necessarily report the current speed
16235 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
16236 {
16237 // report the max possible speed
16238 rssidx = 0;
16239 }
16240 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
16241 {
16242 // report the max possible speed with RSSI scaling
16243 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
16244 {
16245 // report the max possible speed
16246 rssidx = 0;
16247 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016248 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070016249 {
16250 // report middle speed
16251 rssidx = 1;
16252 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016253 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
16254 {
16255 // report middle speed
16256 rssidx = 2;
16257 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016258 else
16259 {
16260 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016261 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070016262 }
16263 }
16264 else
16265 {
16266 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
16267 hddLog(VOS_TRACE_LEVEL_ERROR,
16268 "%s: Invalid value for reportMaxLinkSpeed: %u",
16269 __func__, pCfg->reportMaxLinkSpeed);
16270 rssidx = 0;
16271 }
16272
16273 maxRate = 0;
16274
16275 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016276 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
16277 OperationalRates, &ORLeng))
16278 {
16279 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16280 /*To keep GUI happy*/
16281 return 0;
16282 }
16283
Jeff Johnson295189b2012-06-20 16:38:30 -070016284 for (i = 0; i < ORLeng; i++)
16285 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016286 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016287 {
16288 /* Validate Rate Set */
16289 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
16290 {
16291 currentRate = supported_data_rate[j].supported_rate[rssidx];
16292 break;
16293 }
16294 }
16295 /* Update MAX rate */
16296 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16297 }
16298
16299 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016300 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
16301 ExtendedRates, &ERLeng))
16302 {
16303 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16304 /*To keep GUI happy*/
16305 return 0;
16306 }
16307
Jeff Johnson295189b2012-06-20 16:38:30 -070016308 for (i = 0; i < ERLeng; i++)
16309 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016310 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016311 {
16312 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
16313 {
16314 currentRate = supported_data_rate[j].supported_rate[rssidx];
16315 break;
16316 }
16317 }
16318 /* Update MAX rate */
16319 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16320 }
c_hpothu79aab322014-07-14 21:11:01 +053016321
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016322 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053016323 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016324 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053016325 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070016326 {
c_hpothu79aab322014-07-14 21:11:01 +053016327 if (rate_flags & eHAL_TX_RATE_VHT80)
16328 mode = 2;
16329 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
16330 mode = 1;
16331 else
16332 mode = 0;
16333
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016334 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
16335 MCSRates, &MCSLeng))
16336 {
16337 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16338 /*To keep GUI happy*/
16339 return 0;
16340 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016341 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070016342#ifdef WLAN_FEATURE_11AC
16343 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016344 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070016345 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016346 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016347 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070016348 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070016349 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016350 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016351 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016352 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070016353 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016354 maxMCSIdx = 7;
16355 }
16356 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
16357 {
16358 maxMCSIdx = 8;
16359 }
16360 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
16361 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016362 //VHT20 is supporting 0~8
16363 if (rate_flags & eHAL_TX_RATE_VHT20)
16364 maxMCSIdx = 8;
16365 else
16366 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070016367 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016368
c_hpothu79aab322014-07-14 21:11:01 +053016369 if (0 != rssidx)/*check for scaled */
16370 {
16371 //get middle rate MCS index if rssi=1/2
16372 for (i=0; i <= maxMCSIdx; i++)
16373 {
16374 if (sinfo->signal <= rssiMcsTbl[mode][i])
16375 {
16376 maxMCSIdx = i;
16377 break;
16378 }
16379 }
16380 }
16381
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016382 if (rate_flags & eHAL_TX_RATE_VHT80)
16383 {
16384 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
16385 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
16386 }
16387 else if (rate_flags & eHAL_TX_RATE_VHT40)
16388 {
16389 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
16390 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
16391 }
16392 else if (rate_flags & eHAL_TX_RATE_VHT20)
16393 {
16394 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
16395 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
16396 }
16397
Leo Chang6f8870f2013-03-26 18:11:36 -070016398 maxSpeedMCS = 1;
16399 if (currentRate > maxRate)
16400 {
16401 maxRate = currentRate;
16402 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016403
Leo Chang6f8870f2013-03-26 18:11:36 -070016404 }
16405 else
16406#endif /* WLAN_FEATURE_11AC */
16407 {
16408 if (rate_flags & eHAL_TX_RATE_HT40)
16409 {
16410 rateFlag |= 1;
16411 }
16412 if (rate_flags & eHAL_TX_RATE_SGI)
16413 {
16414 rateFlag |= 2;
16415 }
16416
Girish Gowli01abcee2014-07-31 20:18:55 +053016417 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053016418 if (rssidx == 1 || rssidx == 2)
16419 {
16420 //get middle rate MCS index if rssi=1/2
16421 for (i=0; i <= 7; i++)
16422 {
16423 if (sinfo->signal <= rssiMcsTbl[mode][i])
16424 {
16425 temp = i+1;
16426 break;
16427 }
16428 }
16429 }
c_hpothu79aab322014-07-14 21:11:01 +053016430
16431 for (i = 0; i < MCSLeng; i++)
16432 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016433 for (j = 0; j < temp; j++)
16434 {
16435 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
16436 {
16437 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016438 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016439 break;
16440 }
16441 }
16442 if ((j < temp) && (currentRate > maxRate))
16443 {
16444 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070016445 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016446 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016447 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016448 }
16449 }
16450
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016451 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
16452 {
16453 maxRate = myRate;
16454 maxSpeedMCS = 1;
16455 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16456 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016457 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053016458 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070016459 {
16460 maxRate = myRate;
16461 if (rate_flags & eHAL_TX_RATE_LEGACY)
16462 {
16463 maxSpeedMCS = 0;
16464 }
16465 else
16466 {
16467 maxSpeedMCS = 1;
16468 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16469 }
16470 }
16471
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016472 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070016473 {
16474 sinfo->txrate.legacy = maxRate;
16475#ifdef LINKSPEED_DEBUG_ENABLED
16476 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
16477#endif //LINKSPEED_DEBUG_ENABLED
16478 }
16479 else
16480 {
16481 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070016482#ifdef WLAN_FEATURE_11AC
16483 sinfo->txrate.nss = 1;
16484 if (rate_flags & eHAL_TX_RATE_VHT80)
16485 {
16486 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016487 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070016488 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016489 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070016490 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016491 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16492 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16493 }
16494 else if (rate_flags & eHAL_TX_RATE_VHT20)
16495 {
16496 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16497 }
16498#endif /* WLAN_FEATURE_11AC */
16499 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
16500 {
16501 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16502 if (rate_flags & eHAL_TX_RATE_HT40)
16503 {
16504 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16505 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016506 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016507 if (rate_flags & eHAL_TX_RATE_SGI)
16508 {
16509 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16510 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016511
Jeff Johnson295189b2012-06-20 16:38:30 -070016512#ifdef LINKSPEED_DEBUG_ENABLED
16513 pr_info("Reporting MCS rate %d flags %x\n",
16514 sinfo->txrate.mcs,
16515 sinfo->txrate.flags );
16516#endif //LINKSPEED_DEBUG_ENABLED
16517 }
16518 }
16519 else
16520 {
16521 // report current rate instead of max rate
16522
16523 if (rate_flags & eHAL_TX_RATE_LEGACY)
16524 {
16525 //provide to the UI in units of 100kbps
16526 sinfo->txrate.legacy = myRate;
16527#ifdef LINKSPEED_DEBUG_ENABLED
16528 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
16529#endif //LINKSPEED_DEBUG_ENABLED
16530 }
16531 else
16532 {
16533 //must be MCS
16534 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016535#ifdef WLAN_FEATURE_11AC
16536 sinfo->txrate.nss = 1;
16537 if (rate_flags & eHAL_TX_RATE_VHT80)
16538 {
16539 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16540 }
16541 else
16542#endif /* WLAN_FEATURE_11AC */
16543 {
16544 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16545 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016546 if (rate_flags & eHAL_TX_RATE_SGI)
16547 {
16548 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16549 }
16550 if (rate_flags & eHAL_TX_RATE_HT40)
16551 {
16552 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16553 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016554#ifdef WLAN_FEATURE_11AC
16555 else if (rate_flags & eHAL_TX_RATE_VHT80)
16556 {
16557 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
16558 }
16559#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070016560#ifdef LINKSPEED_DEBUG_ENABLED
16561 pr_info("Reporting actual MCS rate %d flags %x\n",
16562 sinfo->txrate.mcs,
16563 sinfo->txrate.flags );
16564#endif //LINKSPEED_DEBUG_ENABLED
16565 }
16566 }
16567 sinfo->filled |= STATION_INFO_TX_BITRATE;
16568
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016569 sinfo->tx_packets =
16570 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
16571 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
16572 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
16573 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
16574
16575 sinfo->tx_retries =
16576 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
16577 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
16578 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
16579 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
16580
16581 sinfo->tx_failed =
16582 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
16583 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
16584 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
16585 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
16586
16587 sinfo->filled |=
16588 STATION_INFO_TX_PACKETS |
16589 STATION_INFO_TX_RETRIES |
16590 STATION_INFO_TX_FAILED;
16591
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053016592 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
16593 sinfo->filled |= STATION_INFO_RX_PACKETS;
16594
16595 if (rate_flags & eHAL_TX_RATE_LEGACY)
16596 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
16597 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
16598 sinfo->rx_packets);
16599 else
16600 hddLog(LOG1,
16601 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
16602 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
16603 sinfo->tx_packets, sinfo->rx_packets);
16604
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016605 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16606 TRACE_CODE_HDD_CFG80211_GET_STA,
16607 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016608 EXIT();
16609 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070016610}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016611#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16612static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16613 const u8* mac, struct station_info *sinfo)
16614#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016615static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16616 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016617#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016618{
16619 int ret;
16620
16621 vos_ssr_protect(__func__);
16622 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
16623 vos_ssr_unprotect(__func__);
16624
16625 return ret;
16626}
16627
16628static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070016629 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070016630{
16631 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016632 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016633 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016634 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016635
Jeff Johnsone7245742012-09-05 17:12:55 -070016636 ENTER();
16637
Jeff Johnson295189b2012-06-20 16:38:30 -070016638 if (NULL == pAdapter)
16639 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016640 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016641 return -ENODEV;
16642 }
16643
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016644 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16645 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
16646 pAdapter->sessionId, timeout));
16647
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016648 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016649 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016650 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016651 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016652 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016653 }
16654
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016655 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
16656 (TRUE == pHddCtx->hdd_wlan_suspended) &&
16657 (pHddCtx->cfg_ini->fhostArpOffload) &&
16658 (eConnectionState_Associated ==
16659 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
16660 {
Amar Singhald53568e2013-09-26 11:03:45 -070016661
16662 hddLog(VOS_TRACE_LEVEL_INFO,
16663 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053016664 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016665 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16666 {
16667 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016668 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016669 __func__, vos_status);
16670 }
16671 }
16672
Jeff Johnson295189b2012-06-20 16:38:30 -070016673 /**The get power cmd from the supplicant gets updated by the nl only
16674 *on successful execution of the function call
16675 *we are oppositely mapped w.r.t mode in the driver
16676 **/
16677 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
16678
16679 if (VOS_STATUS_E_FAILURE == vos_status)
16680 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16682 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016683 return -EINVAL;
16684 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016685 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016686 return 0;
16687}
16688
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016689static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
16690 struct net_device *dev, bool mode, int timeout)
16691{
16692 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016693
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016694 vos_ssr_protect(__func__);
16695 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
16696 vos_ssr_unprotect(__func__);
16697
16698 return ret;
16699}
Sushant Kaushik084f6592015-09-10 13:11:56 +053016700
Jeff Johnson295189b2012-06-20 16:38:30 -070016701#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016702static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
16703 struct net_device *netdev,
16704 u8 key_index)
16705{
16706 ENTER();
16707 return 0;
16708}
16709
Jeff Johnson295189b2012-06-20 16:38:30 -070016710static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016711 struct net_device *netdev,
16712 u8 key_index)
16713{
16714 int ret;
16715 vos_ssr_protect(__func__);
16716 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
16717 vos_ssr_unprotect(__func__);
16718 return ret;
16719}
16720#endif //LINUX_VERSION_CODE
16721
16722#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16723static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16724 struct net_device *dev,
16725 struct ieee80211_txq_params *params)
16726{
16727 ENTER();
16728 return 0;
16729}
16730#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16731static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16732 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016733{
Jeff Johnsone7245742012-09-05 17:12:55 -070016734 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070016735 return 0;
16736}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016737#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070016738
16739#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16740static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016741 struct net_device *dev,
16742 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016743{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016744 int ret;
16745
16746 vos_ssr_protect(__func__);
16747 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
16748 vos_ssr_unprotect(__func__);
16749 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016750}
16751#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16752static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
16753 struct ieee80211_txq_params *params)
16754{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016755 int ret;
16756
16757 vos_ssr_protect(__func__);
16758 ret = __wlan_hdd_set_txq_params(wiphy, params);
16759 vos_ssr_unprotect(__func__);
16760 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016761}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016762#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016763
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016764static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016765 struct net_device *dev,
16766 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070016767{
16768 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016769 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016770 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016771 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016772 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016773 v_CONTEXT_t pVosContext = NULL;
16774 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016775
Jeff Johnsone7245742012-09-05 17:12:55 -070016776 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016777
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016778 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070016779 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016780 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016781 return -EINVAL;
16782 }
16783
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016784 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16785 TRACE_CODE_HDD_CFG80211_DEL_STA,
16786 pAdapter->sessionId, pAdapter->device_mode));
16787
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016788 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16789 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016790 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016791 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016792 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016793 }
16794
Jeff Johnson295189b2012-06-20 16:38:30 -070016795 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016796 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016797 )
16798 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016799 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
16800 pSapCtx = VOS_GET_SAP_CB(pVosContext);
16801 if(pSapCtx == NULL){
16802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16803 FL("psapCtx is NULL"));
16804 return -ENOENT;
16805 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053016806 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
16807 {
16808 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
16809 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
16810 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
16811 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016812 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070016813 {
16814 v_U16_t i;
16815 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
16816 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016817 if ((pSapCtx->aStaInfo[i].isUsed) &&
16818 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070016819 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016820 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016821 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016822 ETHER_ADDR_LEN);
16823
Jeff Johnson295189b2012-06-20 16:38:30 -070016824 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016825 "%s: Delete STA with MAC::"
16826 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016827 __func__,
16828 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
16829 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070016830 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016831 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016832 }
16833 }
16834 }
16835 else
16836 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016837
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016838 vos_status = hdd_softap_GetStaId(pAdapter,
16839 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016840 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16841 {
16842 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016843 "%s: Skip this DEL STA as this is not used::"
16844 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016845 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016846 return -ENOENT;
16847 }
16848
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016849 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016850 {
16851 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016852 "%s: Skip this DEL STA as deauth is in progress::"
16853 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016854 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016855 return -ENOENT;
16856 }
16857
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016858 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016859
Jeff Johnson295189b2012-06-20 16:38:30 -070016860 hddLog(VOS_TRACE_LEVEL_INFO,
16861 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016862 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016863 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016864 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016865
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016866 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016867 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16868 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016869 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016870 hddLog(VOS_TRACE_LEVEL_INFO,
16871 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016872 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016873 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016874 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016875 return -ENOENT;
16876 }
16877
Jeff Johnson295189b2012-06-20 16:38:30 -070016878 }
16879 }
16880
16881 EXIT();
16882
16883 return 0;
16884}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016885
16886#ifdef CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053016887int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016888 struct net_device *dev,
16889 struct station_del_parameters *param)
16890#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016891#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053016892int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016893 struct net_device *dev, const u8 *mac)
16894#else
Kapil Gupta137ef892016-12-13 19:38:00 +053016895int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016896 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016897#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016898#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016899{
16900 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016901 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016902
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016903 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016904
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016905#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016906 if (NULL == param) {
16907 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016908 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016909 return -EINVAL;
16910 }
16911
16912 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16913 param->subtype, &delStaParams);
16914
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016915#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016916 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016917 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016918#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016919 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16920
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016921 vos_ssr_unprotect(__func__);
16922
16923 return ret;
16924}
16925
16926static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016927 struct net_device *dev,
16928#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16929 const u8 *mac,
16930#else
16931 u8 *mac,
16932#endif
16933 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016934{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016935 hdd_adapter_t *pAdapter;
16936 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016937 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016938#ifdef FEATURE_WLAN_TDLS
16939 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016940
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016941 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016942
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016943 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16944 if (NULL == pAdapter)
16945 {
16946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16947 "%s: Adapter is NULL",__func__);
16948 return -EINVAL;
16949 }
16950 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16951 status = wlan_hdd_validate_context(pHddCtx);
16952 if (0 != status)
16953 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016954 return status;
16955 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016956
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016957 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16958 TRACE_CODE_HDD_CFG80211_ADD_STA,
16959 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016960 mask = params->sta_flags_mask;
16961
16962 set = params->sta_flags_set;
16963
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016965 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
16966 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016967
16968 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
16969 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080016970 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016971 }
16972 }
16973#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016974 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016975 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016976}
16977
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016978#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16979static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16980 struct net_device *dev, const u8 *mac,
16981 struct station_parameters *params)
16982#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016983static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16984 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016985#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016986{
16987 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016988
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016989 vos_ssr_protect(__func__);
16990 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
16991 vos_ssr_unprotect(__func__);
16992
16993 return ret;
16994}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016995#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070016996
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016997static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070016998 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016999{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017000 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17001 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017002 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017003 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017004 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017005 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070017006
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017007 ENTER();
17008
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017009 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017010 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017011 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017012 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017013 return -EINVAL;
17014 }
17015
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017016 if (!pmksa) {
17017 hddLog(LOGE, FL("pmksa is NULL"));
17018 return -EINVAL;
17019 }
17020
17021 if (!pmksa->bssid || !pmksa->pmkid) {
17022 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
17023 pmksa->bssid, pmksa->pmkid);
17024 return -EINVAL;
17025 }
17026
17027 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
17028 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17029
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017030 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17031 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017032 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017033 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017034 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017035 }
17036
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017037 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017038 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17039
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017040 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
17041 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017042
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017043 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017044 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017045 &pmk_id, 1, FALSE);
17046
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017047 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17048 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
17049 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017050
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017051 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017052 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017053}
17054
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017055static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
17056 struct cfg80211_pmksa *pmksa)
17057{
17058 int ret;
17059
17060 vos_ssr_protect(__func__);
17061 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
17062 vos_ssr_unprotect(__func__);
17063
17064 return ret;
17065}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017066
Wilson Yang6507c4e2013-10-01 20:11:19 -070017067
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017068static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070017069 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017070{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017071 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17072 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017073 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017074 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017075
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017076 ENTER();
17077
Wilson Yang6507c4e2013-10-01 20:11:19 -070017078 /* Validate pAdapter */
17079 if (NULL == pAdapter)
17080 {
17081 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
17082 return -EINVAL;
17083 }
17084
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017085 if (!pmksa) {
17086 hddLog(LOGE, FL("pmksa is NULL"));
17087 return -EINVAL;
17088 }
17089
17090 if (!pmksa->bssid) {
17091 hddLog(LOGE, FL("pmksa->bssid is NULL"));
17092 return -EINVAL;
17093 }
17094
Kiet Lam98c46a12014-10-31 15:34:57 -070017095 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
17096 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17097
Wilson Yang6507c4e2013-10-01 20:11:19 -070017098 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17099 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017100 if (0 != status)
17101 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017102 return status;
17103 }
17104
17105 /*Retrieve halHandle*/
17106 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17107
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017108 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17109 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
17110 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017111 /* Delete the PMKID CSR cache */
17112 if (eHAL_STATUS_SUCCESS !=
17113 sme_RoamDelPMKIDfromCache(halHandle,
17114 pAdapter->sessionId, pmksa->bssid, FALSE)) {
17115 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
17116 MAC_ADDR_ARRAY(pmksa->bssid));
17117 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017118 }
17119
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017120 EXIT();
17121 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017122}
17123
Wilson Yang6507c4e2013-10-01 20:11:19 -070017124
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017125static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
17126 struct cfg80211_pmksa *pmksa)
17127{
17128 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017129
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017130 vos_ssr_protect(__func__);
17131 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
17132 vos_ssr_unprotect(__func__);
17133
17134 return ret;
17135
17136}
17137
17138static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017139{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017140 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17141 tHalHandle halHandle;
17142 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017143 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017144
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017145 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070017146
17147 /* Validate pAdapter */
17148 if (NULL == pAdapter)
17149 {
17150 hddLog(VOS_TRACE_LEVEL_ERROR,
17151 "%s: Invalid Adapter" ,__func__);
17152 return -EINVAL;
17153 }
17154
17155 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17156 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017157 if (0 != status)
17158 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017159 return status;
17160 }
17161
17162 /*Retrieve halHandle*/
17163 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17164
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017165 /* Flush the PMKID cache in CSR */
17166 if (eHAL_STATUS_SUCCESS !=
17167 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
17168 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
17169 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017170 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017171 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080017172 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017173}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017174
17175static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
17176{
17177 int ret;
17178
17179 vos_ssr_protect(__func__);
17180 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
17181 vos_ssr_unprotect(__func__);
17182
17183 return ret;
17184}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017185#endif
17186
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017187#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017188static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17189 struct net_device *dev,
17190 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017191{
17192 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17193 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017194 hdd_context_t *pHddCtx;
17195 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017196
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017197 ENTER();
17198
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017199 if (NULL == pAdapter)
17200 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017201 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017202 return -ENODEV;
17203 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017204 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17205 ret = wlan_hdd_validate_context(pHddCtx);
17206 if (0 != ret)
17207 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017208 return ret;
17209 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017210 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017211 if (NULL == pHddStaCtx)
17212 {
17213 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
17214 return -EINVAL;
17215 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017216
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017217 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17218 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
17219 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017220 // Added for debug on reception of Re-assoc Req.
17221 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
17222 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017223 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017224 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080017225 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017226 }
17227
17228#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080017229 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017230 ftie->ie_len);
17231#endif
17232
17233 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053017234 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
17235 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017236 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017237
17238 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017239 return 0;
17240}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017241
17242static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17243 struct net_device *dev,
17244 struct cfg80211_update_ft_ies_params *ftie)
17245{
17246 int ret;
17247
17248 vos_ssr_protect(__func__);
17249 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
17250 vos_ssr_unprotect(__func__);
17251
17252 return ret;
17253}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017254#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017255
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017256#ifdef FEATURE_WLAN_SCAN_PNO
17257
17258void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
17259 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
17260{
17261 int ret;
17262 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
17263 hdd_context_t *pHddCtx;
17264
Nirav Shah80830bf2013-12-31 16:35:12 +053017265 ENTER();
17266
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017267 if (NULL == pAdapter)
17268 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053017269 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017270 "%s: HDD adapter is Null", __func__);
17271 return ;
17272 }
17273
17274 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17275 if (NULL == pHddCtx)
17276 {
17277 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17278 "%s: HDD context is Null!!!", __func__);
17279 return ;
17280 }
17281
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017282 spin_lock(&pHddCtx->schedScan_lock);
17283 if (TRUE == pHddCtx->isWiphySuspended)
17284 {
17285 pHddCtx->isSchedScanUpdatePending = TRUE;
17286 spin_unlock(&pHddCtx->schedScan_lock);
17287 hddLog(VOS_TRACE_LEVEL_INFO,
17288 "%s: Update cfg80211 scan database after it resume", __func__);
17289 return ;
17290 }
17291 spin_unlock(&pHddCtx->schedScan_lock);
17292
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017293 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
17294
17295 if (0 > ret)
17296 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053017297 else
17298 {
17299 /* Acquire wakelock to handle the case where APP's tries to suspend
17300 * immediatly after the driver gets connect request(i.e after pno)
17301 * from supplicant, this result in app's is suspending and not able
17302 * to process the connect request to AP */
17303 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
17304 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017305 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17307 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017308}
17309
17310/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017311 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017312 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017313 */
17314static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
17315{
17316 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
17317 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017318 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017319 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17320 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053017321
17322 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
17323 {
17324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17325 "%s: PNO is allowed only in STA interface", __func__);
17326 return eHAL_STATUS_FAILURE;
17327 }
17328
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017329 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
17330
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017331 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053017332 * active sessions. PNO is allowed only in case when sap session
17333 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017334 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017335 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
17336 {
17337 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017338 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017339
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017340 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
17341 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
17342 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
17343 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053017344 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
17345 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053017346 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017347 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017348 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017349 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017350 }
17351 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17352 pAdapterNode = pNext;
17353 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017354 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017355}
17356
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017357void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
17358{
17359 hdd_adapter_t *pAdapter = callbackContext;
17360 hdd_context_t *pHddCtx;
17361
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017362 ENTER();
17363
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017364 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
17365 {
17366 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17367 FL("Invalid adapter or adapter has invalid magic"));
17368 return;
17369 }
17370
17371 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17372 if (0 != wlan_hdd_validate_context(pHddCtx))
17373 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017374 return;
17375 }
17376
c_hpothub53c45d2014-08-18 16:53:14 +053017377 if (VOS_STATUS_SUCCESS != status)
17378 {
17379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017380 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053017381 pHddCtx->isPnoEnable = FALSE;
17382 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017383
17384 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
17385 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017386 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017387}
17388
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017389#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
17390 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
17391/**
17392 * hdd_config_sched_scan_plan() - configures the sched scan plans
17393 * from the framework.
17394 * @pno_req: pointer to PNO scan request
17395 * @request: pointer to scan request from framework
17396 *
17397 * Return: None
17398 */
17399static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
17400 struct cfg80211_sched_scan_request *request,
17401 hdd_context_t *hdd_ctx)
17402{
17403 v_U32_t i = 0;
17404
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017405 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017406 for (i = 0; i < request->n_scan_plans; i++)
17407 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017408 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
17409 request->scan_plans[i].iterations;
17410 pno_req->scanTimers.aTimerValues[i].uTimerValue =
17411 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017412 }
17413}
17414#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017415static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017416 struct cfg80211_sched_scan_request *request,
17417 hdd_context_t *hdd_ctx)
17418{
17419 v_U32_t i, temp_int;
17420 /* Driver gets only one time interval which is hardcoded in
17421 * supplicant for 10000ms. Taking power consumption into account 6
17422 * timers will be used, Timervalue is increased exponentially
17423 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
17424 * timer is configurable through INI param gPNOScanTimerRepeatValue.
17425 * If it is set to 0 only one timer will be used and PNO scan cycle
17426 * will be repeated after each interval specified by supplicant
17427 * till PNO is disabled.
17428 */
17429 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017430 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017431 HDD_PNO_SCAN_TIMERS_SET_ONE;
17432 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017433 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017434 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
17435
17436 temp_int = (request->interval)/1000;
17437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17438 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
17439 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017440 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017441 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017442 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017443 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017444 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017445 temp_int *= 2;
17446 }
17447 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017448 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017449}
17450#endif
17451
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017452/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017453 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
17454 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017455 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017456static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017457 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17458{
17459 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017460 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017461 hdd_context_t *pHddCtx;
17462 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017463 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053017464 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
17465 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017466 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17467 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017468 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017469 hdd_config_t *pConfig = NULL;
17470 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017471
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017472 ENTER();
17473
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017474 if (NULL == pAdapter)
17475 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017477 "%s: HDD adapter is Null", __func__);
17478 return -ENODEV;
17479 }
17480
17481 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017482 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017483
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017484 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017485 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017486 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017487 }
17488
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017489 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017490 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17491 if (NULL == hHal)
17492 {
17493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17494 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017495 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017496 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017497 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17498 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
17499 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053017500 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053017501 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053017502 {
17503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17504 "%s: aborting the existing scan is unsuccessfull", __func__);
17505 return -EBUSY;
17506 }
17507
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017508 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017509 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017511 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017512 return -EBUSY;
17513 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017514
c_hpothu37f21312014-04-09 21:49:54 +053017515 if (TRUE == pHddCtx->isPnoEnable)
17516 {
17517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17518 FL("already PNO is enabled"));
17519 return -EBUSY;
17520 }
c_hpothu225aa7c2014-10-22 17:45:13 +053017521
17522 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
17523 {
17524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17525 "%s: abort ROC failed ", __func__);
17526 return -EBUSY;
17527 }
17528
c_hpothu37f21312014-04-09 21:49:54 +053017529 pHddCtx->isPnoEnable = TRUE;
17530
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017531 pnoRequest.enable = 1; /*Enable PNO */
17532 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017533
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017534 if (( !pnoRequest.ucNetworksCount ) ||
17535 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017536 {
17537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017538 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017539 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017540 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017541 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017542 goto error;
17543 }
17544
17545 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
17546 {
17547 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017548 "%s: Incorrect number of channels %d",
17549 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017550 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017551 goto error;
17552 }
17553
17554 /* Framework provides one set of channels(all)
17555 * common for all saved profile */
17556 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17557 channels_allowed, &num_channels_allowed))
17558 {
17559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17560 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017561 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017562 goto error;
17563 }
17564 /* Checking each channel against allowed channel list */
17565 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053017566 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017567 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017568 char chList [(request->n_channels*5)+1];
17569 int len;
17570 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017571 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017572 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017573 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017574 if (request->channels[i]->hw_value == channels_allowed[indx])
17575 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017576 if ((!pConfig->enableDFSPnoChnlScan) &&
17577 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
17578 {
17579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17580 "%s : Dropping DFS channel : %d",
17581 __func__,channels_allowed[indx]);
17582 num_ignore_dfs_ch++;
17583 break;
17584 }
17585
Nirav Shah80830bf2013-12-31 16:35:12 +053017586 valid_ch[num_ch++] = request->channels[i]->hw_value;
17587 len += snprintf(chList+len, 5, "%d ",
17588 request->channels[i]->hw_value);
17589 break ;
17590 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017591 }
17592 }
Nirav Shah80830bf2013-12-31 16:35:12 +053017593 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017594
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017595 /*If all channels are DFS and dropped, then ignore the PNO request*/
17596 if (num_ignore_dfs_ch == request->n_channels)
17597 {
17598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17599 "%s : All requested channels are DFS channels", __func__);
17600 ret = -EINVAL;
17601 goto error;
17602 }
17603 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017604
17605 pnoRequest.aNetworks =
17606 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17607 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017608 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017609 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17610 FL("failed to allocate memory aNetworks %u"),
17611 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17612 goto error;
17613 }
17614 vos_mem_zero(pnoRequest.aNetworks,
17615 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17616
17617 /* Filling per profile params */
17618 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
17619 {
17620 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017621 request->match_sets[i].ssid.ssid_len;
17622
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017623 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
17624 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017625 {
17626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017627 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017628 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017629 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017630 goto error;
17631 }
17632
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017633 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017634 request->match_sets[i].ssid.ssid,
17635 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17637 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017638 i, pnoRequest.aNetworks[i].ssId.ssId);
17639 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
17640 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
17641 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017642
17643 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017644 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
17645 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017646
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017647 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017648 }
17649
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017650 for (i = 0; i < request->n_ssids; i++)
17651 {
17652 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017653 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017654 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017655 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017656 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017657 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017658 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017659 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017660 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017661 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017662 break;
17663 }
17664 j++;
17665 }
17666 }
17667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17668 "Number of hidden networks being Configured = %d",
17669 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080017671 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017672
17673 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17674 if (pnoRequest.p24GProbeTemplate == NULL)
17675 {
17676 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17677 FL("failed to allocate memory p24GProbeTemplate %u"),
17678 SIR_PNO_MAX_PB_REQ_SIZE);
17679 goto error;
17680 }
17681
17682 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17683 if (pnoRequest.p5GProbeTemplate == NULL)
17684 {
17685 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17686 FL("failed to allocate memory p5GProbeTemplate %u"),
17687 SIR_PNO_MAX_PB_REQ_SIZE);
17688 goto error;
17689 }
17690
17691 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17692 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17693
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053017694 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
17695 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017696 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017697 pnoRequest.us24GProbeTemplateLen = request->ie_len;
17698 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
17699 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017700
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017701 pnoRequest.us5GProbeTemplateLen = request->ie_len;
17702 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
17703 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017704 }
17705
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017706 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017707
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017708 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017709
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017710 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017711 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17712 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017713 pAdapter->pno_req_status = 0;
17714
Nirav Shah80830bf2013-12-31 16:35:12 +053017715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17716 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017717 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
17718 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053017719
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017720 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017721 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017722 hdd_cfg80211_sched_scan_done_callback, pAdapter);
17723 if (eHAL_STATUS_SUCCESS != status)
17724 {
17725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017726 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017727 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017728 goto error;
17729 }
17730
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017731 ret = wait_for_completion_timeout(
17732 &pAdapter->pno_comp_var,
17733 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17734 if (0 >= ret)
17735 {
17736 // Did not receive the response for PNO enable in time.
17737 // Assuming the PNO enable was success.
17738 // Returning error from here, because we timeout, results
17739 // in side effect of Wifi (Wifi Setting) not to work.
17740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17741 FL("Timed out waiting for PNO to be Enabled"));
17742 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017743 }
17744
17745 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053017746 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017747
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017748error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17750 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053017751 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017752 if (pnoRequest.aNetworks)
17753 vos_mem_free(pnoRequest.aNetworks);
17754 if (pnoRequest.p24GProbeTemplate)
17755 vos_mem_free(pnoRequest.p24GProbeTemplate);
17756 if (pnoRequest.p5GProbeTemplate)
17757 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017758
17759 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017760 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017761}
17762
17763/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017764 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
17765 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017766 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017767static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
17768 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17769{
17770 int ret;
17771
17772 vos_ssr_protect(__func__);
17773 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
17774 vos_ssr_unprotect(__func__);
17775
17776 return ret;
17777}
17778
17779/*
17780 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
17781 * Function to disable PNO
17782 */
17783static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017784 struct net_device *dev)
17785{
17786 eHalStatus status = eHAL_STATUS_FAILURE;
17787 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17788 hdd_context_t *pHddCtx;
17789 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017790 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017791 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017792
17793 ENTER();
17794
17795 if (NULL == pAdapter)
17796 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017797 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017798 "%s: HDD adapter is Null", __func__);
17799 return -ENODEV;
17800 }
17801
17802 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017803
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017804 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017805 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017807 "%s: HDD context is Null", __func__);
17808 return -ENODEV;
17809 }
17810
17811 /* The return 0 is intentional when isLogpInProgress and
17812 * isLoadUnloadInProgress. We did observe a crash due to a return of
17813 * failure in sched_scan_stop , especially for a case where the unload
17814 * of the happens at the same time. The function __cfg80211_stop_sched_scan
17815 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
17816 * success. If it returns a failure , then its next invocation due to the
17817 * clean up of the second interface will have the dev pointer corresponding
17818 * to the first one leading to a crash.
17819 */
17820 if (pHddCtx->isLogpInProgress)
17821 {
17822 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17823 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053017824 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017825 return ret;
17826 }
17827
Mihir Shete18156292014-03-11 15:38:30 +053017828 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017829 {
17830 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17831 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17832 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017833 }
17834
17835 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17836 if (NULL == hHal)
17837 {
17838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17839 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017840 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017841 }
17842
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017843 pnoRequest.enable = 0; /* Disable PNO */
17844 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017845
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017846 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17847 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
17848 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017849
17850 INIT_COMPLETION(pAdapter->pno_comp_var);
17851 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17852 pnoRequest.callbackContext = pAdapter;
17853 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017854 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017855 pAdapter->sessionId,
17856 NULL, pAdapter);
17857 if (eHAL_STATUS_SUCCESS != status)
17858 {
17859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17860 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017861 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017862 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017863 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017864 ret = wait_for_completion_timeout(
17865 &pAdapter->pno_comp_var,
17866 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17867 if (0 >= ret)
17868 {
17869 // Did not receive the response for PNO disable in time.
17870 // Assuming the PNO disable was success.
17871 // Returning error from here, because we timeout, results
17872 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053017873 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017874 FL("Timed out waiting for PNO to be disabled"));
17875 ret = 0;
17876 }
17877
17878 ret = pAdapter->pno_req_status;
17879 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017880
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017881error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017882 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017883 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017884
17885 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017886 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017887}
17888
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017889/*
17890 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
17891 * NL interface to disable PNO
17892 */
17893static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
17894 struct net_device *dev)
17895{
17896 int ret;
17897
17898 vos_ssr_protect(__func__);
17899 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
17900 vos_ssr_unprotect(__func__);
17901
17902 return ret;
17903}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017904#endif /*FEATURE_WLAN_SCAN_PNO*/
17905
17906
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017907#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017908#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017909static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17910 struct net_device *dev,
17911 u8 *peer, u8 action_code,
17912 u8 dialog_token,
17913 u16 status_code, u32 peer_capability,
17914 const u8 *buf, size_t len)
17915#else /* TDLS_MGMT_VERSION2 */
17916#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17917static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17918 struct net_device *dev,
17919 const u8 *peer, u8 action_code,
17920 u8 dialog_token, u16 status_code,
17921 u32 peer_capability, bool initiator,
17922 const u8 *buf, size_t len)
17923#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17924static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17925 struct net_device *dev,
17926 const u8 *peer, u8 action_code,
17927 u8 dialog_token, u16 status_code,
17928 u32 peer_capability, const u8 *buf,
17929 size_t len)
17930#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17931static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17932 struct net_device *dev,
17933 u8 *peer, u8 action_code,
17934 u8 dialog_token,
17935 u16 status_code, u32 peer_capability,
17936 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017937#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017938static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17939 struct net_device *dev,
17940 u8 *peer, u8 action_code,
17941 u8 dialog_token,
17942 u16 status_code, const u8 *buf,
17943 size_t len)
17944#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017945#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017946{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017947 hdd_adapter_t *pAdapter;
17948 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017949 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070017950 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080017951 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070017952 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017953 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017954 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017955#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017956 u32 peer_capability = 0;
17957#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017958 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017959 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053017960 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017961
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017962 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17963 if (NULL == pAdapter)
17964 {
17965 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17966 "%s: Adapter is NULL",__func__);
17967 return -EINVAL;
17968 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017969 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17970 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
17971 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017972
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017973 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017974 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017975 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017976 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017977 "Invalid arguments");
17978 return -EINVAL;
17979 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017980
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017981 if (pHddCtx->isLogpInProgress)
17982 {
17983 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17984 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053017985 wlan_hdd_tdls_set_link_status(pAdapter,
17986 peer,
17987 eTDLS_LINK_IDLE,
17988 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017989 return -EBUSY;
17990 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017991
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017992 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
17993 {
17994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17995 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17996 return -EAGAIN;
17997 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017998
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053017999 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
18000 if (!pHddTdlsCtx) {
18001 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18002 "%s: pHddTdlsCtx not valid.", __func__);
18003 }
18004
Hoonki Lee27511902013-03-14 18:19:06 -070018005 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018006 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018008 "%s: TDLS mode is disabled OR not enabled in FW."
18009 MAC_ADDRESS_STR " action %d declined.",
18010 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018011 return -ENOTSUPP;
18012 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018013
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018014 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18015
18016 if( NULL == pHddStaCtx )
18017 {
18018 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18019 "%s: HDD station context NULL ",__func__);
18020 return -EINVAL;
18021 }
18022
18023 /* STA should be connected and authenticated
18024 * before sending any TDLS frames
18025 */
18026 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18027 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
18028 {
18029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18030 "STA is not connected or unauthenticated. "
18031 "connState %u, uIsAuthenticated %u",
18032 pHddStaCtx->conn_info.connState,
18033 pHddStaCtx->conn_info.uIsAuthenticated);
18034 return -EAGAIN;
18035 }
18036
Hoonki Lee27511902013-03-14 18:19:06 -070018037 /* other than teardown frame, other mgmt frames are not sent if disabled */
18038 if (SIR_MAC_TDLS_TEARDOWN != action_code)
18039 {
18040 /* if tdls_mode is disabled to respond to peer's request */
18041 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
18042 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018044 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018045 " TDLS mode is disabled. action %d declined.",
18046 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070018047
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018048 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070018049 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053018050
18051 if (vos_max_concurrent_connections_reached())
18052 {
18053 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
18054 return -EINVAL;
18055 }
Hoonki Lee27511902013-03-14 18:19:06 -070018056 }
18057
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018058 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
18059 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053018060 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018061 {
18062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018063 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018064 " TDLS setup is ongoing. action %d declined.",
18065 __func__, MAC_ADDR_ARRAY(peer), action_code);
18066 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018067 }
18068 }
18069
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018070 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
18071 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080018072 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018073 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18074 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018075 {
18076 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
18077 we return error code at 'add_station()'. Hence we have this
18078 check again in addtion to add_station().
18079 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018080 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018081 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18083 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018084 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
18085 __func__, MAC_ADDR_ARRAY(peer), action_code,
18086 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053018087 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080018088 }
18089 else
18090 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018091 /* maximum reached. tweak to send error code to peer and return
18092 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018093 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18095 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018096 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
18097 __func__, MAC_ADDR_ARRAY(peer), status_code,
18098 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070018099 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018100 /* fall through to send setup resp with failure status
18101 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018102 }
18103 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018104 else
18105 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018106 mutex_lock(&pHddCtx->tdls_lock);
18107 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018108 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018109 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018110 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018111 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018112 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
18113 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018114 return -EPERM;
18115 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018116 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018117 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018118 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018119
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018121 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018122 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
18123 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018124
Hoonki Leea34dd892013-02-05 22:56:02 -080018125 /*Except teardown responder will not be used so just make 0*/
18126 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018127 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080018128 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018129
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018130 mutex_lock(&pHddCtx->tdls_lock);
18131 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018132
18133 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
18134 responder = pTdlsPeer->is_responder;
18135 else
Hoonki Leea34dd892013-02-05 22:56:02 -080018136 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018137 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018138 "%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 -070018139 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
18140 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018141 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018142 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080018143 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018144 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018145 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018146
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053018147 /* Discard TDLS setup if peer is removed by user app */
18148 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
18149 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18150 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
18151 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
18152
18153 mutex_lock(&pHddCtx->tdls_lock);
18154 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18155 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
18156 mutex_unlock(&pHddCtx->tdls_lock);
18157 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
18158 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
18159 MAC_ADDR_ARRAY(peer), action_code);
18160 return -EINVAL;
18161 }
18162 mutex_unlock(&pHddCtx->tdls_lock);
18163 }
18164
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018165 /* For explicit trigger of DIS_REQ come out of BMPS for
18166 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070018167 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053018168 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018169 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
18170 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070018171 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018172 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018173 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018174 "%s: Sending frame action_code %u.Disable BMPS", __func__,
18175 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018176 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
18177 if (status != VOS_STATUS_SUCCESS) {
18178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018179 } else {
18180 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018181 }
Hoonki Lee14621352013-04-16 17:51:19 -070018182 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018183 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018184 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018185 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
18186 }
18187 }
Hoonki Lee14621352013-04-16 17:51:19 -070018188 }
18189
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018190 /* make sure doesn't call send_mgmt() while it is pending */
18191 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
18192 {
18193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018194 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018195 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018196 ret = -EBUSY;
18197 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018198 }
18199
18200 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018201 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
18202
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018203 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
18204 pAdapter->sessionId, peer, action_code, dialog_token,
18205 status_code, peer_capability, (tANI_U8 *)buf, len,
18206 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018207
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018208 if (VOS_STATUS_SUCCESS != status)
18209 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18211 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018212 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018213 ret = -EINVAL;
18214 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018215 }
18216
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18218 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
18219 WAIT_TIME_TDLS_MGMT);
18220
Hoonki Leed37cbb32013-04-20 00:31:14 -070018221 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
18222 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
18223
18224 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018225 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070018226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070018227 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070018228 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018229 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080018230
18231 if (pHddCtx->isLogpInProgress)
18232 {
18233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18234 "%s: LOGP in Progress. Ignore!!!", __func__);
18235 return -EAGAIN;
18236 }
Abhishek Singh837adf22015-10-01 17:37:37 +053018237 if (rc <= 0)
18238 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
18239 WLAN_LOG_INDICATOR_HOST_DRIVER,
18240 WLAN_LOG_REASON_HDD_TIME_OUT,
18241 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080018242
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018243 ret = -EINVAL;
18244 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018245 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018246 else
18247 {
18248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18249 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
18250 __func__, rc, pAdapter->mgmtTxCompletionStatus);
18251 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018252
Gopichand Nakkala05922802013-03-14 12:23:19 -070018253 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070018254 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018255 ret = max_sta_failed;
18256 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070018257 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018258
Hoonki Leea34dd892013-02-05 22:56:02 -080018259 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
18260 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018261 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018262 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18263 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018264 }
18265 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
18266 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018267 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018268 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18269 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018270 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018271
18272 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018273
18274tx_failed:
18275 /* add_station will be called before sending TDLS_SETUP_REQ and
18276 * TDLS_SETUP_RSP and as part of add_station driver will enable
18277 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
18278 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
18279 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
18280 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
18281 */
18282
18283 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18284 (SIR_MAC_TDLS_SETUP_RSP == action_code))
18285 wlan_hdd_tdls_check_bmps(pAdapter);
18286 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018287}
18288
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018289#if TDLS_MGMT_VERSION2
18290static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18291 u8 *peer, u8 action_code, u8 dialog_token,
18292 u16 status_code, u32 peer_capability,
18293 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018294#else /* TDLS_MGMT_VERSION2 */
18295#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18296static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18297 struct net_device *dev,
18298 const u8 *peer, u8 action_code,
18299 u8 dialog_token, u16 status_code,
18300 u32 peer_capability, bool initiator,
18301 const u8 *buf, size_t len)
18302#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18303static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18304 struct net_device *dev,
18305 const u8 *peer, u8 action_code,
18306 u8 dialog_token, u16 status_code,
18307 u32 peer_capability, const u8 *buf,
18308 size_t len)
18309#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18310static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18311 struct net_device *dev,
18312 u8 *peer, u8 action_code,
18313 u8 dialog_token,
18314 u16 status_code, u32 peer_capability,
18315 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018316#else
18317static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18318 u8 *peer, u8 action_code, u8 dialog_token,
18319 u16 status_code, const u8 *buf, size_t len)
18320#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018321#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018322{
18323 int ret;
18324
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018325 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018326#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018327 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18328 dialog_token, status_code,
18329 peer_capability, buf, len);
18330#else /* TDLS_MGMT_VERSION2 */
18331#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
18332 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18333 dialog_token, status_code,
18334 peer_capability, initiator,
18335 buf, len);
18336#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
18337 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18338 dialog_token, status_code,
18339 peer_capability, buf, len);
18340#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
18341 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18342 dialog_token, status_code,
18343 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018344#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018345 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18346 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018347#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018348#endif
18349 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018350
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018351 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018352}
Atul Mittal115287b2014-07-08 13:26:33 +053018353
18354int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018355#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18356 const u8 *peer,
18357#else
Atul Mittal115287b2014-07-08 13:26:33 +053018358 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018359#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018360 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053018361 cfg80211_exttdls_callback callback)
18362{
18363
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018364 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053018365 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018366 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053018367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18368 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
18369 __func__, MAC_ADDR_ARRAY(peer));
18370
18371 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18372 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18373
18374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018375 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18376 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18377 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018378 return -ENOTSUPP;
18379 }
18380
18381 /* To cater the requirement of establishing the TDLS link
18382 * irrespective of the data traffic , get an entry of TDLS peer.
18383 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053018384 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018385 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
18386 if (pTdlsPeer == NULL) {
18387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18388 "%s: peer " MAC_ADDRESS_STR " not existing",
18389 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053018390 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018391 return -EINVAL;
18392 }
18393
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053018394 /* check FW TDLS Off Channel capability */
18395 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053018396 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053018397 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018398 {
18399 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
18400 pTdlsPeer->peerParams.global_operating_class =
18401 tdls_peer_params->global_operating_class;
18402 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
18403 pTdlsPeer->peerParams.min_bandwidth_kbps =
18404 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018405 /* check configured channel is valid, non dfs and
18406 * not current operating channel */
18407 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
18408 tdls_peer_params->channel)) &&
18409 (pHddStaCtx) &&
18410 (tdls_peer_params->channel !=
18411 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018412 {
18413 pTdlsPeer->isOffChannelConfigured = TRUE;
18414 }
18415 else
18416 {
18417 pTdlsPeer->isOffChannelConfigured = FALSE;
18418 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18419 "%s: Configured Tdls Off Channel is not valid", __func__);
18420
18421 }
18422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018423 "%s: tdls_off_channel %d isOffChannelConfigured %d "
18424 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018425 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018426 pTdlsPeer->isOffChannelConfigured,
18427 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018428 }
18429 else
18430 {
18431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053018432 "%s: TDLS off channel FW capability %d, "
18433 "host capab %d or Invalid TDLS Peer Params", __func__,
18434 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
18435 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018436 }
18437
Atul Mittal115287b2014-07-08 13:26:33 +053018438 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
18439
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018440 mutex_unlock(&pHddCtx->tdls_lock);
18441
Atul Mittal115287b2014-07-08 13:26:33 +053018442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18443 " %s TDLS Add Force Peer Failed",
18444 __func__);
18445 return -EINVAL;
18446 }
18447 /*EXT TDLS*/
18448
18449 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018450 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018451 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18452 " %s TDLS set callback Failed",
18453 __func__);
18454 return -EINVAL;
18455 }
18456
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018457 mutex_unlock(&pHddCtx->tdls_lock);
18458
Atul Mittal115287b2014-07-08 13:26:33 +053018459 return(0);
18460
18461}
18462
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018463int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
18464#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18465 const u8 *peer
18466#else
18467 u8 *peer
18468#endif
18469)
Atul Mittal115287b2014-07-08 13:26:33 +053018470{
18471
18472 hddTdlsPeer_t *pTdlsPeer;
18473 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053018474
Atul Mittal115287b2014-07-08 13:26:33 +053018475 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18476 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
18477 __func__, MAC_ADDR_ARRAY(peer));
18478
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018479 if (0 != wlan_hdd_validate_context(pHddCtx)) {
18480 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
18481 return -EINVAL;
18482 }
18483
Atul Mittal115287b2014-07-08 13:26:33 +053018484 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18485 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18486
18487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018488 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18489 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18490 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018491 return -ENOTSUPP;
18492 }
18493
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018494 mutex_lock(&pHddCtx->tdls_lock);
18495 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053018496
18497 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018498 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018499 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018500 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053018501 __func__, MAC_ADDR_ARRAY(peer));
18502 return -EINVAL;
18503 }
18504 else {
18505 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
18506 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053018507 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
18508 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018509 /* if channel switch is configured, reset
18510 the channel for this peer */
18511 if (TRUE == pTdlsPeer->isOffChannelConfigured)
18512 {
18513 pTdlsPeer->peerParams.channel = 0;
18514 pTdlsPeer->isOffChannelConfigured = FALSE;
18515 }
Atul Mittal115287b2014-07-08 13:26:33 +053018516 }
18517
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018518 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018519 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018520 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053018521 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018522 }
Atul Mittal115287b2014-07-08 13:26:33 +053018523
18524 /*EXT TDLS*/
18525
18526 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018527 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18529 " %s TDLS set callback Failed",
18530 __func__);
18531 return -EINVAL;
18532 }
Atul Mittal115287b2014-07-08 13:26:33 +053018533
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018534 mutex_unlock(&pHddCtx->tdls_lock);
18535
18536 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053018537}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018538static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018539#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18540 const u8 *peer,
18541#else
18542 u8 *peer,
18543#endif
18544 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018545{
18546 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18547 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018548 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018549 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018550
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018551 ENTER();
18552
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018553 if (!pAdapter) {
18554 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
18555 return -EINVAL;
18556 }
18557
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018558 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18559 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
18560 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018561 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018562 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070018564 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018565 return -EINVAL;
18566 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018567
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018568 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018569 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018570 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018571 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018572 }
18573
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018574
18575 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018576 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018577 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018579 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
18580 "Cannot process TDLS commands",
18581 pHddCtx->cfg_ini->fEnableTDLSSupport,
18582 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018583 return -ENOTSUPP;
18584 }
18585
18586 switch (oper) {
18587 case NL80211_TDLS_ENABLE_LINK:
18588 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018589 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018590 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053018591 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
18592 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053018593 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018594 tANI_U16 numCurrTdlsPeers = 0;
18595 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018596 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018597 tSirMacAddr peerMac;
18598 int channel;
18599 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018600
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18602 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
18603 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018604
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018605 mutex_lock(&pHddCtx->tdls_lock);
18606 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018607 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053018608 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018609 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018610 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18611 " (oper %d) not exsting. ignored",
18612 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18613 return -EINVAL;
18614 }
18615
18616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18617 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18618 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18619 "NL80211_TDLS_ENABLE_LINK");
18620
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018621 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
18622 {
18623 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
18624 MAC_ADDRESS_STR " failed",
18625 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018626 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018627 return -EINVAL;
18628 }
18629
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018630 /* before starting tdls connection, set tdls
18631 * off channel established status to default value */
18632 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018633
18634 mutex_unlock(&pHddCtx->tdls_lock);
18635
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053018636 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018637 /* TDLS Off Channel, Disable tdls channel switch,
18638 when there are more than one tdls link */
18639 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053018640 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018641 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018642 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018643 /* get connected peer and send disable tdls off chan */
18644 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018645 if ((connPeer) &&
18646 (connPeer->isOffChannelSupported == TRUE) &&
18647 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018648 {
18649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18650 "%s: More then one peer connected, Disable "
18651 "TDLS channel switch", __func__);
18652
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018653 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018654 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
18655 channel = connPeer->peerParams.channel;
18656
18657 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018658
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018659 ret = sme_SendTdlsChanSwitchReq(
18660 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018661 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018662 peerMac,
18663 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018664 TDLS_OFF_CHANNEL_BW_OFFSET,
18665 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018666 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018667 hddLog(VOS_TRACE_LEVEL_ERROR,
18668 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018669 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018670 }
18671 else
18672 {
18673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18674 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018675 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018676 "isOffChannelConfigured %d",
18677 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018678 (connPeer ? (connPeer->isOffChannelSupported)
18679 : -1),
18680 (connPeer ? (connPeer->isOffChannelConfigured)
18681 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018682 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018683 }
18684 }
18685
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018686 mutex_lock(&pHddCtx->tdls_lock);
18687 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18688 if ( NULL == pTdlsPeer ) {
18689 mutex_unlock(&pHddCtx->tdls_lock);
18690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18691 "%s: " MAC_ADDRESS_STR
18692 " (oper %d) peer got freed in other context. ignored",
18693 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18694 return -EINVAL;
18695 }
18696 peer_status = pTdlsPeer->link_status;
18697 mutex_unlock(&pHddCtx->tdls_lock);
18698
18699 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018700 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018701 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053018702
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018703 if (0 != wlan_hdd_tdls_get_link_establish_params(
18704 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018705 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018706 return -EINVAL;
18707 }
18708 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018709
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018710 ret = sme_SendTdlsLinkEstablishParams(
18711 WLAN_HDD_GET_HAL_CTX(pAdapter),
18712 pAdapter->sessionId, peer,
18713 &tdlsLinkEstablishParams);
18714 if (ret != VOS_STATUS_SUCCESS) {
18715 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
18716 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018717 /* Send TDLS peer UAPSD capabilities to the firmware and
18718 * register with the TL on after the response for this operation
18719 * is received .
18720 */
18721 ret = wait_for_completion_interruptible_timeout(
18722 &pAdapter->tdls_link_establish_req_comp,
18723 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053018724
18725 mutex_lock(&pHddCtx->tdls_lock);
18726 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18727 if ( NULL == pTdlsPeer ) {
18728 mutex_unlock(&pHddCtx->tdls_lock);
18729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18730 "%s %d: " MAC_ADDRESS_STR
18731 " (oper %d) peer got freed in other context. ignored",
18732 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
18733 (int)oper);
18734 return -EINVAL;
18735 }
18736 peer_status = pTdlsPeer->link_status;
18737 mutex_unlock(&pHddCtx->tdls_lock);
18738
18739 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018740 {
18741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018742 FL("Link Establish Request Failed Status %ld"),
18743 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018744 return -EINVAL;
18745 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018746 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018747
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018748 mutex_lock(&pHddCtx->tdls_lock);
18749 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18750 if ( NULL == pTdlsPeer ) {
18751 mutex_unlock(&pHddCtx->tdls_lock);
18752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18753 "%s: " MAC_ADDRESS_STR
18754 " (oper %d) peer got freed in other context. ignored",
18755 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18756 return -EINVAL;
18757 }
18758
Atul Mittal115287b2014-07-08 13:26:33 +053018759 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18760 eTDLS_LINK_CONNECTED,
18761 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018762 staDesc.ucSTAId = pTdlsPeer->staId;
18763 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053018764
18765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18766 "%s: tdlsLinkEstablishParams of peer "
18767 MAC_ADDRESS_STR "uapsdQueues: %d"
18768 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
18769 "isResponder: %d peerstaId: %d",
18770 __func__,
18771 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
18772 tdlsLinkEstablishParams.uapsdQueues,
18773 tdlsLinkEstablishParams.qos,
18774 tdlsLinkEstablishParams.maxSp,
18775 tdlsLinkEstablishParams.isBufSta,
18776 tdlsLinkEstablishParams.isOffChannelSupported,
18777 tdlsLinkEstablishParams.isResponder,
18778 pTdlsPeer->staId);
18779
18780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18781 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
18782 __func__,
18783 staDesc.ucSTAId,
18784 staDesc.ucQosEnabled);
18785
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018786 ret = WLANTL_UpdateTdlsSTAClient(
18787 pHddCtx->pvosContext,
18788 &staDesc);
18789 if (ret != VOS_STATUS_SUCCESS) {
18790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
18791 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053018792
Gopichand Nakkala471708b2013-06-04 20:03:01 +053018793 /* Mark TDLS client Authenticated .*/
18794 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
18795 pTdlsPeer->staId,
18796 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018797 if (VOS_STATUS_SUCCESS == status)
18798 {
Hoonki Lee14621352013-04-16 17:51:19 -070018799 if (pTdlsPeer->is_responder == 0)
18800 {
18801 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018802 tdlsConnInfo_t *tdlsInfo;
18803
18804 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
18805
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018806 if (!vos_timer_is_initialized(
18807 &pTdlsPeer->initiatorWaitTimeoutTimer))
18808 {
18809 /* Initialize initiator wait callback */
18810 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018811 &pTdlsPeer->initiatorWaitTimeoutTimer,
18812 VOS_TIMER_TYPE_SW,
18813 wlan_hdd_tdls_initiator_wait_cb,
18814 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018815 }
Hoonki Lee14621352013-04-16 17:51:19 -070018816 wlan_hdd_tdls_timer_restart(pAdapter,
18817 &pTdlsPeer->initiatorWaitTimeoutTimer,
18818 WAIT_TIME_TDLS_INITIATOR);
18819 /* suspend initiator TX until it receives direct packet from the
18820 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018821 ret = WLANTL_SuspendDataTx(
18822 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18823 &staId, NULL);
18824 if (ret != VOS_STATUS_SUCCESS) {
18825 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
18826 }
Hoonki Lee14621352013-04-16 17:51:19 -070018827 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018828
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018829 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018830 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018831 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018832 suppChannelLen =
18833 tdlsLinkEstablishParams.supportedChannelsLen;
18834
18835 if ((suppChannelLen > 0) &&
18836 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
18837 {
18838 tANI_U8 suppPeerChannel = 0;
18839 int i = 0;
18840 for (i = 0U; i < suppChannelLen; i++)
18841 {
18842 suppPeerChannel =
18843 tdlsLinkEstablishParams.supportedChannels[i];
18844
18845 pTdlsPeer->isOffChannelSupported = FALSE;
18846 if (suppPeerChannel ==
18847 pTdlsPeer->peerParams.channel)
18848 {
18849 pTdlsPeer->isOffChannelSupported = TRUE;
18850 break;
18851 }
18852 }
18853 }
18854 else
18855 {
18856 pTdlsPeer->isOffChannelSupported = FALSE;
18857 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018858 }
18859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18860 "%s: TDLS channel switch request for channel "
18861 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018862 "%d isOffChannelSupported %d", __func__,
18863 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018864 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018865 suppChannelLen,
18866 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018867
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018868 /* TDLS Off Channel, Enable tdls channel switch,
18869 when their is only one tdls link and it supports */
18870 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18871 if ((numCurrTdlsPeers == 1) &&
18872 (TRUE == pTdlsPeer->isOffChannelSupported) &&
18873 (TRUE == pTdlsPeer->isOffChannelConfigured))
18874 {
18875 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18876 "%s: Send TDLS channel switch request for channel %d",
18877 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018878
18879 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018880 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
18881 channel = pTdlsPeer->peerParams.channel;
18882
18883 mutex_unlock(&pHddCtx->tdls_lock);
18884
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018885 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
18886 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018887 peerMac,
18888 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018889 TDLS_OFF_CHANNEL_BW_OFFSET,
18890 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018891 if (ret != VOS_STATUS_SUCCESS) {
18892 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
18893 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018894 }
18895 else
18896 {
18897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18898 "%s: TDLS channel switch request not sent"
18899 " numCurrTdlsPeers %d "
18900 "isOffChannelSupported %d "
18901 "isOffChannelConfigured %d",
18902 __func__, numCurrTdlsPeers,
18903 pTdlsPeer->isOffChannelSupported,
18904 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018905 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018906 }
18907
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018908 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018909 else
18910 mutex_unlock(&pHddCtx->tdls_lock);
18911
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018912 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018913
18914 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018915 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
18916 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018917 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018918 int ac;
18919 uint8 ucAc[4] = { WLANTL_AC_VO,
18920 WLANTL_AC_VI,
18921 WLANTL_AC_BK,
18922 WLANTL_AC_BE };
18923 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
18924 for(ac=0; ac < 4; ac++)
18925 {
18926 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18927 pTdlsPeer->staId, ucAc[ac],
18928 tlTid[ac], tlTid[ac], 0, 0,
18929 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018930 if (status != VOS_STATUS_SUCCESS) {
18931 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
18932 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018933 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018934 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018935 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018936
Bhargav Shah66896792015-10-01 18:17:37 +053018937 /* stop TCP delack timer if TDLS is enable */
18938 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18939 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053018940 hdd_wlan_tdls_enable_link_event(peer,
18941 pTdlsPeer->isOffChannelSupported,
18942 pTdlsPeer->isOffChannelConfigured,
18943 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018944 }
18945 break;
18946 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080018947 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018948 tANI_U16 numCurrTdlsPeers = 0;
18949 hddTdlsPeer_t *connPeer = NULL;
18950
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018951 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18952 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
18953 __func__, MAC_ADDR_ARRAY(peer));
18954
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018955 mutex_lock(&pHddCtx->tdls_lock);
18956 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018957
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018958
Sunil Dutt41de4e22013-11-14 18:09:02 +053018959 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018960 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018961 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18962 " (oper %d) not exsting. ignored",
18963 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18964 return -EINVAL;
18965 }
18966
18967 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18968 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18969 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18970 "NL80211_TDLS_DISABLE_LINK");
18971
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018972 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080018973 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018974 long status;
18975
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018976 /* set tdls off channel status to false for this peer */
18977 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053018978 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18979 eTDLS_LINK_TEARING,
18980 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
18981 eTDLS_LINK_UNSPECIFIED:
18982 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018983 mutex_unlock(&pHddCtx->tdls_lock);
18984
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018985 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
18986
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018987 status = sme_DeleteTdlsPeerSta(
18988 WLAN_HDD_GET_HAL_CTX(pAdapter),
18989 pAdapter->sessionId, peer );
18990 if (status != VOS_STATUS_SUCCESS) {
18991 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
18992 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018993
18994 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
18995 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018996
18997 mutex_lock(&pHddCtx->tdls_lock);
18998 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18999 if ( NULL == pTdlsPeer ) {
19000 mutex_unlock(&pHddCtx->tdls_lock);
19001 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19002 " peer was freed in other context",
19003 __func__, MAC_ADDR_ARRAY(peer));
19004 return -EINVAL;
19005 }
19006
Atul Mittal271a7652014-09-12 13:18:22 +053019007 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053019008 eTDLS_LINK_IDLE,
19009 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019010 mutex_unlock(&pHddCtx->tdls_lock);
19011
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019012 if (status <= 0)
19013 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19015 "%s: Del station failed status %ld",
19016 __func__, status);
19017 return -EPERM;
19018 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019019
19020 /* TDLS Off Channel, Enable tdls channel switch,
19021 when their is only one tdls link and it supports */
19022 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19023 if (numCurrTdlsPeers == 1)
19024 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019025 tSirMacAddr peerMac;
19026 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019027
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019028 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019029 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019030
19031 if (connPeer == NULL) {
19032 mutex_unlock(&pHddCtx->tdls_lock);
19033 hddLog(VOS_TRACE_LEVEL_ERROR,
19034 "%s connPeer is NULL", __func__);
19035 return -EINVAL;
19036 }
19037
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019038 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
19039 channel = connPeer->peerParams.channel;
19040
19041 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19042 "%s: TDLS channel switch "
19043 "isOffChannelSupported %d "
19044 "isOffChannelConfigured %d "
19045 "isOffChannelEstablished %d",
19046 __func__,
19047 (connPeer ? connPeer->isOffChannelSupported : -1),
19048 (connPeer ? connPeer->isOffChannelConfigured : -1),
19049 (connPeer ? connPeer->isOffChannelEstablished : -1));
19050
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019051 if ((connPeer) &&
19052 (connPeer->isOffChannelSupported == TRUE) &&
19053 (connPeer->isOffChannelConfigured == TRUE))
19054 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019055 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019056 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019057 status = sme_SendTdlsChanSwitchReq(
19058 WLAN_HDD_GET_HAL_CTX(pAdapter),
19059 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019060 peerMac,
19061 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019062 TDLS_OFF_CHANNEL_BW_OFFSET,
19063 TDLS_CHANNEL_SWITCH_ENABLE);
19064 if (status != VOS_STATUS_SUCCESS) {
19065 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
19066 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019067 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019068 else
19069 mutex_unlock(&pHddCtx->tdls_lock);
19070 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019071 else
19072 {
19073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19074 "%s: TDLS channel switch request not sent "
19075 "numCurrTdlsPeers %d ",
19076 __func__, numCurrTdlsPeers);
19077 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019078 }
19079 else
19080 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019081 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19083 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080019084 }
Bhargav Shah66896792015-10-01 18:17:37 +053019085 if (numCurrTdlsPeers == 0) {
19086 /* start TCP delack timer if TDLS is disable */
19087 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
19088 hdd_manage_delack_timer(pHddCtx);
19089 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019090 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019091 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019092 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019093 {
Atul Mittal115287b2014-07-08 13:26:33 +053019094 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019095
Atul Mittal115287b2014-07-08 13:26:33 +053019096 if (0 != status)
19097 {
19098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019099 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053019100 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019101 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053019102 break;
19103 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019104 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019105 {
Atul Mittal115287b2014-07-08 13:26:33 +053019106 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
19107 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019108 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053019109 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019110
Atul Mittal115287b2014-07-08 13:26:33 +053019111 if (0 != status)
19112 {
19113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019114 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053019115 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053019116 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053019117 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019118 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019119 case NL80211_TDLS_DISCOVERY_REQ:
19120 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019121 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019122 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019123 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019124 return -ENOTSUPP;
19125 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019126 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19127 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019128 return -ENOTSUPP;
19129 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019130
19131 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019132 return 0;
19133}
Chilam NG571c65a2013-01-19 12:27:36 +053019134
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019135static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019136#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19137 const u8 *peer,
19138#else
19139 u8 *peer,
19140#endif
19141 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019142{
19143 int ret;
19144
19145 vos_ssr_protect(__func__);
19146 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
19147 vos_ssr_unprotect(__func__);
19148
19149 return ret;
19150}
19151
Chilam NG571c65a2013-01-19 12:27:36 +053019152int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
19153 struct net_device *dev, u8 *peer)
19154{
Arif Hussaina7c8e412013-11-20 11:06:42 -080019155 hddLog(VOS_TRACE_LEVEL_INFO,
19156 "tdls send discover req: "MAC_ADDRESS_STR,
19157 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019158#if TDLS_MGMT_VERSION2
19159 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19160 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19161#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019162#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19163 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19164 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
19165#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19166 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19167 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19168#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19169 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19170 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19171#else
Chilam NG571c65a2013-01-19 12:27:36 +053019172 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19173 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019174#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019175#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053019176}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019177#endif
19178
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019179#ifdef WLAN_FEATURE_GTK_OFFLOAD
19180/*
19181 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
19182 * Callback rountine called upon receiving response for
19183 * get offload info
19184 */
19185void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
19186 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
19187{
19188
19189 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019190 tANI_U8 tempReplayCounter[8];
19191 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019192
19193 ENTER();
19194
19195 if (NULL == pAdapter)
19196 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019198 "%s: HDD adapter is Null", __func__);
19199 return ;
19200 }
19201
19202 if (NULL == pGtkOffloadGetInfoRsp)
19203 {
19204 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19205 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
19206 return ;
19207 }
19208
19209 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
19210 {
19211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19212 "%s: wlan Failed to get replay counter value",
19213 __func__);
19214 return ;
19215 }
19216
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019217 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19218 /* Update replay counter */
19219 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
19220 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19221
19222 {
19223 /* changing from little to big endian since supplicant
19224 * works on big endian format
19225 */
19226 int i;
19227 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19228
19229 for (i = 0; i < 8; i++)
19230 {
19231 tempReplayCounter[7-i] = (tANI_U8)p[i];
19232 }
19233 }
19234
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019235 /* Update replay counter to NL */
19236 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019237 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019238}
19239
19240/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019241 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019242 * This function is used to offload GTK rekeying job to the firmware.
19243 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019244int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019245 struct cfg80211_gtk_rekey_data *data)
19246{
19247 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19248 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19249 hdd_station_ctx_t *pHddStaCtx;
19250 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019251 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019252 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019253 eHalStatus status = eHAL_STATUS_FAILURE;
19254
19255 ENTER();
19256
19257 if (NULL == pAdapter)
19258 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019260 "%s: HDD adapter is Null", __func__);
19261 return -ENODEV;
19262 }
19263
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019264 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19265 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
19266 pAdapter->sessionId, pAdapter->device_mode));
19267
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019268 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019269 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019270 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019271 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019272 }
19273
19274 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19275 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19276 if (NULL == hHal)
19277 {
19278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19279 "%s: HAL context is Null!!!", __func__);
19280 return -EAGAIN;
19281 }
19282
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019283 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
19284 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
19285 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
19286 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019287 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019288 {
19289 /* changing from big to little endian since driver
19290 * works on little endian format
19291 */
19292 tANI_U8 *p =
19293 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
19294 int i;
19295
19296 for (i = 0; i < 8; i++)
19297 {
19298 p[7-i] = data->replay_ctr[i];
19299 }
19300 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019301
19302 if (TRUE == pHddCtx->hdd_wlan_suspended)
19303 {
19304 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019305 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
19306 sizeof (tSirGtkOffloadParams));
19307 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019308 pAdapter->sessionId);
19309
19310 if (eHAL_STATUS_SUCCESS != status)
19311 {
19312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19313 "%s: sme_SetGTKOffload failed, returned %d",
19314 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019315
19316 /* Need to clear any trace of key value in the memory.
19317 * Thus zero out the memory even though it is local
19318 * variable.
19319 */
19320 vos_mem_zero(&hddGtkOffloadReqParams,
19321 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019322 return status;
19323 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19325 "%s: sme_SetGTKOffload successfull", __func__);
19326 }
19327 else
19328 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19330 "%s: wlan not suspended GTKOffload request is stored",
19331 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019332 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019333
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019334 /* Need to clear any trace of key value in the memory.
19335 * Thus zero out the memory even though it is local
19336 * variable.
19337 */
19338 vos_mem_zero(&hddGtkOffloadReqParams,
19339 sizeof(hddGtkOffloadReqParams));
19340
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019341 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019342 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019343}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019344
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019345int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
19346 struct cfg80211_gtk_rekey_data *data)
19347{
19348 int ret;
19349
19350 vos_ssr_protect(__func__);
19351 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
19352 vos_ssr_unprotect(__func__);
19353
19354 return ret;
19355}
19356#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019357/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019358 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019359 * This function is used to set access control policy
19360 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019361static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19362 struct net_device *dev,
19363 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019364{
19365 int i;
19366 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19367 hdd_hostapd_state_t *pHostapdState;
19368 tsap_Config_t *pConfig;
19369 v_CONTEXT_t pVosContext = NULL;
19370 hdd_context_t *pHddCtx;
19371 int status;
19372
19373 ENTER();
19374
19375 if (NULL == pAdapter)
19376 {
19377 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19378 "%s: HDD adapter is Null", __func__);
19379 return -ENODEV;
19380 }
19381
19382 if (NULL == params)
19383 {
19384 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19385 "%s: params is Null", __func__);
19386 return -EINVAL;
19387 }
19388
19389 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19390 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019391 if (0 != status)
19392 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019393 return status;
19394 }
19395
19396 pVosContext = pHddCtx->pvosContext;
19397 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
19398
19399 if (NULL == pHostapdState)
19400 {
19401 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19402 "%s: pHostapdState is Null", __func__);
19403 return -EINVAL;
19404 }
19405
19406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
19407 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019408 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19409 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
19410 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019411
19412 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
19413 {
19414 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
19415
19416 /* default value */
19417 pConfig->num_accept_mac = 0;
19418 pConfig->num_deny_mac = 0;
19419
19420 /**
19421 * access control policy
19422 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
19423 * listed in hostapd.deny file.
19424 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
19425 * listed in hostapd.accept file.
19426 */
19427 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
19428 {
19429 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
19430 }
19431 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
19432 {
19433 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
19434 }
19435 else
19436 {
19437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19438 "%s:Acl Policy : %d is not supported",
19439 __func__, params->acl_policy);
19440 return -ENOTSUPP;
19441 }
19442
19443 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
19444 {
19445 pConfig->num_accept_mac = params->n_acl_entries;
19446 for (i = 0; i < params->n_acl_entries; i++)
19447 {
19448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19449 "** Add ACL MAC entry %i in WhiletList :"
19450 MAC_ADDRESS_STR, i,
19451 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
19452
19453 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
19454 sizeof(qcmacaddr));
19455 }
19456 }
19457 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
19458 {
19459 pConfig->num_deny_mac = params->n_acl_entries;
19460 for (i = 0; i < params->n_acl_entries; i++)
19461 {
19462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19463 "** Add ACL MAC entry %i in BlackList :"
19464 MAC_ADDRESS_STR, i,
19465 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
19466
19467 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
19468 sizeof(qcmacaddr));
19469 }
19470 }
19471
19472 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
19473 {
19474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19475 "%s: SAP Set Mac Acl fail", __func__);
19476 return -EINVAL;
19477 }
19478 }
19479 else
19480 {
19481 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053019482 "%s: Invalid device_mode = %s (%d)",
19483 __func__, hdd_device_modetoString(pAdapter->device_mode),
19484 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019485 return -EINVAL;
19486 }
19487
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019488 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019489 return 0;
19490}
19491
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019492static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19493 struct net_device *dev,
19494 const struct cfg80211_acl_data *params)
19495{
19496 int ret;
19497 vos_ssr_protect(__func__);
19498 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
19499 vos_ssr_unprotect(__func__);
19500
19501 return ret;
19502}
19503
Leo Chang9056f462013-08-01 19:21:11 -070019504#ifdef WLAN_NL80211_TESTMODE
19505#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070019506void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070019507(
19508 void *pAdapter,
19509 void *indCont
19510)
19511{
Leo Changd9df8aa2013-09-26 13:32:26 -070019512 tSirLPHBInd *lphbInd;
19513 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053019514 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070019515
19516 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019517 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070019518
c_hpothu73f35e62014-04-18 13:40:08 +053019519 if (pAdapter == NULL)
19520 {
19521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19522 "%s: pAdapter is NULL\n",__func__);
19523 return;
19524 }
19525
Leo Chang9056f462013-08-01 19:21:11 -070019526 if (NULL == indCont)
19527 {
19528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019529 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070019530 return;
19531 }
19532
c_hpothu73f35e62014-04-18 13:40:08 +053019533 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070019534 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070019535 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053019536 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070019537 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070019538 GFP_ATOMIC);
19539 if (!skb)
19540 {
19541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19542 "LPHB timeout, NL buffer alloc fail");
19543 return;
19544 }
19545
Leo Changac3ba772013-10-07 09:47:04 -070019546 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070019547 {
19548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19549 "WLAN_HDD_TM_ATTR_CMD put fail");
19550 goto nla_put_failure;
19551 }
Leo Changac3ba772013-10-07 09:47:04 -070019552 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070019553 {
19554 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19555 "WLAN_HDD_TM_ATTR_TYPE put fail");
19556 goto nla_put_failure;
19557 }
Leo Changac3ba772013-10-07 09:47:04 -070019558 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070019559 sizeof(tSirLPHBInd), lphbInd))
19560 {
19561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19562 "WLAN_HDD_TM_ATTR_DATA put fail");
19563 goto nla_put_failure;
19564 }
Leo Chang9056f462013-08-01 19:21:11 -070019565 cfg80211_testmode_event(skb, GFP_ATOMIC);
19566 return;
19567
19568nla_put_failure:
19569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19570 "NLA Put fail");
19571 kfree_skb(skb);
19572
19573 return;
19574}
19575#endif /* FEATURE_WLAN_LPHB */
19576
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019577static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070019578{
19579 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
19580 int err = 0;
19581#ifdef FEATURE_WLAN_LPHB
19582 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070019583 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019584
19585 ENTER();
19586
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019587 err = wlan_hdd_validate_context(pHddCtx);
19588 if (0 != err)
19589 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019590 return err;
19591 }
Leo Chang9056f462013-08-01 19:21:11 -070019592#endif /* FEATURE_WLAN_LPHB */
19593
19594 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
19595 if (err)
19596 {
19597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19598 "%s Testmode INV ATTR", __func__);
19599 return err;
19600 }
19601
19602 if (!tb[WLAN_HDD_TM_ATTR_CMD])
19603 {
19604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19605 "%s Testmode INV CMD", __func__);
19606 return -EINVAL;
19607 }
19608
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019609 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19610 TRACE_CODE_HDD_CFG80211_TESTMODE,
19611 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070019612 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
19613 {
19614#ifdef FEATURE_WLAN_LPHB
19615 /* Low Power Heartbeat configuration request */
19616 case WLAN_HDD_TM_CMD_WLAN_HB:
19617 {
19618 int buf_len;
19619 void *buf;
19620 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080019621 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070019622
19623 if (!tb[WLAN_HDD_TM_ATTR_DATA])
19624 {
19625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19626 "%s Testmode INV DATA", __func__);
19627 return -EINVAL;
19628 }
19629
19630 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
19631 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080019632
Manjeet Singh3c577442017-02-10 19:03:38 +053019633 if (buf_len > sizeof(*hb_params)) {
19634 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
19635 buf_len);
19636 return -ERANGE;
19637 }
19638
Amar Singhal05852702014-02-04 14:40:00 -080019639 hb_params_temp =(tSirLPHBReq *)buf;
19640 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
19641 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
19642 return -EINVAL;
19643
Leo Chang9056f462013-08-01 19:21:11 -070019644 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
19645 if (NULL == hb_params)
19646 {
19647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19648 "%s Request Buffer Alloc Fail", __func__);
19649 return -EINVAL;
19650 }
19651
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053019652 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070019653 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070019654 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
19655 hb_params,
19656 wlan_hdd_cfg80211_lphb_ind_handler);
19657 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070019658 {
Leo Changd9df8aa2013-09-26 13:32:26 -070019659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19660 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070019661 vos_mem_free(hb_params);
19662 }
Leo Chang9056f462013-08-01 19:21:11 -070019663 return 0;
19664 }
19665#endif /* FEATURE_WLAN_LPHB */
19666 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19668 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070019669 return -EOPNOTSUPP;
19670 }
19671
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019672 EXIT();
19673 return err;
Leo Chang9056f462013-08-01 19:21:11 -070019674}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019675
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053019676static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
19677#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
19678 struct wireless_dev *wdev,
19679#endif
19680 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019681{
19682 int ret;
19683
19684 vos_ssr_protect(__func__);
19685 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
19686 vos_ssr_unprotect(__func__);
19687
19688 return ret;
19689}
Leo Chang9056f462013-08-01 19:21:11 -070019690#endif /* CONFIG_NL80211_TESTMODE */
19691
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019692extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019693static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019694 struct net_device *dev,
19695 int idx, struct survey_info *survey)
19696{
19697 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19698 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053019699 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019700 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053019701 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019702 v_S7_t snr,rssi;
19703 int status, i, j, filled = 0;
19704
19705 ENTER();
19706
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019707 if (NULL == pAdapter)
19708 {
19709 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19710 "%s: HDD adapter is Null", __func__);
19711 return -ENODEV;
19712 }
19713
19714 if (NULL == wiphy)
19715 {
19716 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19717 "%s: wiphy is Null", __func__);
19718 return -ENODEV;
19719 }
19720
19721 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19722 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019723 if (0 != status)
19724 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019725 return status;
19726 }
19727
Mihir Sheted9072e02013-08-21 17:02:29 +053019728 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19729
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019730 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053019731 0 != pAdapter->survey_idx ||
19732 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019733 {
19734 /* The survey dump ops when implemented completely is expected to
19735 * return a survey of all channels and the ops is called by the
19736 * kernel with incremental values of the argument 'idx' till it
19737 * returns -ENONET. But we can only support the survey for the
19738 * operating channel for now. survey_idx is used to track
19739 * that the ops is called only once and then return -ENONET for
19740 * the next iteration
19741 */
19742 pAdapter->survey_idx = 0;
19743 return -ENONET;
19744 }
19745
Mukul Sharma9d5233b2015-06-11 20:28:20 +053019746 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
19747 {
19748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19749 "%s: Roaming in progress, hence return ", __func__);
19750 return -ENONET;
19751 }
19752
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019753 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19754
19755 wlan_hdd_get_snr(pAdapter, &snr);
19756 wlan_hdd_get_rssi(pAdapter, &rssi);
19757
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019758 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19759 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
19760 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019761 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
19762 hdd_wlan_get_freq(channel, &freq);
19763
19764
19765 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
19766 {
19767 if (NULL == wiphy->bands[i])
19768 {
19769 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
19770 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
19771 continue;
19772 }
19773
19774 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
19775 {
19776 struct ieee80211_supported_band *band = wiphy->bands[i];
19777
19778 if (band->channels[j].center_freq == (v_U16_t)freq)
19779 {
19780 survey->channel = &band->channels[j];
19781 /* The Rx BDs contain SNR values in dB for the received frames
19782 * while the supplicant expects noise. So we calculate and
19783 * return the value of noise (dBm)
19784 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
19785 */
19786 survey->noise = rssi - snr;
19787 survey->filled = SURVEY_INFO_NOISE_DBM;
19788 filled = 1;
19789 }
19790 }
19791 }
19792
19793 if (filled)
19794 pAdapter->survey_idx = 1;
19795 else
19796 {
19797 pAdapter->survey_idx = 0;
19798 return -ENONET;
19799 }
19800
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019801 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019802 return 0;
19803}
19804
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019805static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
19806 struct net_device *dev,
19807 int idx, struct survey_info *survey)
19808{
19809 int ret;
19810
19811 vos_ssr_protect(__func__);
19812 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
19813 vos_ssr_unprotect(__func__);
19814
19815 return ret;
19816}
19817
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019818/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019819 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019820 * this is called when cfg80211 driver resume
19821 * driver updates latest sched_scan scan result(if any) to cfg80211 database
19822 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019823int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019824{
19825 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19826 hdd_adapter_t *pAdapter;
19827 hdd_adapter_list_node_t *pAdapterNode, *pNext;
19828 VOS_STATUS status = VOS_STATUS_SUCCESS;
19829
19830 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019831
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019832 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019833 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019834 return 0;
19835 }
19836
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019837 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
19838 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019839
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053019840 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019841 {
19842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19843 "%s: Resume SoftAP", __func__);
19844 hdd_set_wlan_suspend_mode(false);
19845 }
19846
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019847 spin_lock(&pHddCtx->schedScan_lock);
19848 pHddCtx->isWiphySuspended = FALSE;
19849 if (TRUE != pHddCtx->isSchedScanUpdatePending)
19850 {
19851 spin_unlock(&pHddCtx->schedScan_lock);
19852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19853 "%s: Return resume is not due to PNO indication", __func__);
19854 return 0;
19855 }
19856 // Reset flag to avoid updatating cfg80211 data old results again
19857 pHddCtx->isSchedScanUpdatePending = FALSE;
19858 spin_unlock(&pHddCtx->schedScan_lock);
19859
19860 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
19861
19862 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
19863 {
19864 pAdapter = pAdapterNode->pAdapter;
19865 if ( (NULL != pAdapter) &&
19866 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
19867 {
19868 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019869 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019870 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19871 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019872 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019873 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019874 {
19875 /* Acquire wakelock to handle the case where APP's tries to
19876 * suspend immediately after updating the scan results. Whis
19877 * results in app's is in suspended state and not able to
19878 * process the connect request to AP
19879 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053019880 hdd_prevent_suspend_timeout(2000,
19881 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019882 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019883 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019884
19885 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19886 "%s : cfg80211 scan result database updated", __func__);
19887
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019888 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019889 return 0;
19890
19891 }
19892 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19893 pAdapterNode = pNext;
19894 }
19895
19896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19897 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019898 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019899 return 0;
19900}
19901
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019902int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
19903{
19904 int ret;
19905
19906 vos_ssr_protect(__func__);
19907 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
19908 vos_ssr_unprotect(__func__);
19909
19910 return ret;
19911}
19912
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019913/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019914 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019915 * this is called when cfg80211 driver suspends
19916 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019917int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019918 struct cfg80211_wowlan *wow)
19919{
19920 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019921 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019922
19923 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019924
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019925 ret = wlan_hdd_validate_context(pHddCtx);
19926 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019927 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019928 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019929 }
19930
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053019931 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19933 "%s: Suspend SoftAP", __func__);
19934 hdd_set_wlan_suspend_mode(true);
19935 }
19936
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019937
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019938 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19939 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
19940 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019941 pHddCtx->isWiphySuspended = TRUE;
19942
19943 EXIT();
19944
19945 return 0;
19946}
19947
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019948int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
19949 struct cfg80211_wowlan *wow)
19950{
19951 int ret;
19952
19953 vos_ssr_protect(__func__);
19954 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
19955 vos_ssr_unprotect(__func__);
19956
19957 return ret;
19958}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019959
19960#ifdef FEATURE_OEM_DATA_SUPPORT
19961static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019962 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019963{
19964 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19965
19966 ENTER();
19967
19968 if (wlan_hdd_validate_context(pHddCtx)) {
19969 return;
19970 }
19971 if (!pMsg)
19972 {
19973 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
19974 return;
19975 }
19976
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019977 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019978
19979 EXIT();
19980 return;
19981
19982}
19983
19984void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019985 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019986{
19987 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19988
19989 ENTER();
19990
19991 if (wlan_hdd_validate_context(pHddCtx)) {
19992 return;
19993 }
19994
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019995 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019996
19997 switch(evType) {
19998 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019999 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020000 break;
20001 default:
20002 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
20003 break;
20004 }
20005 EXIT();
20006}
20007#endif
20008
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020009#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20010 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020011/**
20012 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
20013 * @wiphy: Pointer to wiphy
20014 * @wdev: Pointer to wireless device structure
20015 *
20016 * This function is used to abort an ongoing scan
20017 *
20018 * Return: None
20019 */
20020static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20021 struct wireless_dev *wdev)
20022{
20023 struct net_device *dev = wdev->netdev;
20024 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
20025 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
20026 int ret;
20027
20028 ENTER();
20029
20030 if (NULL == adapter) {
20031 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
20032 return;
20033 }
20034
20035 ret = wlan_hdd_validate_context(hdd_ctx);
20036 if (0 != ret)
20037 return;
20038
20039 wlan_hdd_scan_abort(adapter);
20040
20041 return;
20042}
20043
20044/**
20045 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
20046 * @wiphy: Pointer to wiphy
20047 * @wdev: Pointer to wireless device structure
20048 *
20049 * Return: None
20050 */
20051void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20052 struct wireless_dev *wdev)
20053{
20054 vos_ssr_protect(__func__);
20055 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
20056 vos_ssr_unprotect(__func__);
20057
20058 return;
20059}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020060#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020061
Jeff Johnson295189b2012-06-20 16:38:30 -070020062/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020063static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070020064{
20065 .add_virtual_intf = wlan_hdd_add_virtual_intf,
20066 .del_virtual_intf = wlan_hdd_del_virtual_intf,
20067 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
20068 .change_station = wlan_hdd_change_station,
20069#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
20070 .add_beacon = wlan_hdd_cfg80211_add_beacon,
20071 .del_beacon = wlan_hdd_cfg80211_del_beacon,
20072 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020073#else
20074 .start_ap = wlan_hdd_cfg80211_start_ap,
20075 .change_beacon = wlan_hdd_cfg80211_change_beacon,
20076 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070020077#endif
20078 .change_bss = wlan_hdd_cfg80211_change_bss,
20079 .add_key = wlan_hdd_cfg80211_add_key,
20080 .get_key = wlan_hdd_cfg80211_get_key,
20081 .del_key = wlan_hdd_cfg80211_del_key,
20082 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020083#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070020084 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020085#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020086 .scan = wlan_hdd_cfg80211_scan,
20087 .connect = wlan_hdd_cfg80211_connect,
20088 .disconnect = wlan_hdd_cfg80211_disconnect,
20089 .join_ibss = wlan_hdd_cfg80211_join_ibss,
20090 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
20091 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
20092 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
20093 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070020094 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
20095 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053020096 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070020097#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
20098 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
20099 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
20100 .set_txq_params = wlan_hdd_set_txq_params,
20101#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020102 .get_station = wlan_hdd_cfg80211_get_station,
20103 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
20104 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020105 .add_station = wlan_hdd_cfg80211_add_station,
20106#ifdef FEATURE_WLAN_LFR
20107 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
20108 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
20109 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
20110#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070020111#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
20112 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
20113#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020114#ifdef FEATURE_WLAN_TDLS
20115 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
20116 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
20117#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020118#ifdef WLAN_FEATURE_GTK_OFFLOAD
20119 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
20120#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020121#ifdef FEATURE_WLAN_SCAN_PNO
20122 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
20123 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
20124#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020125 .resume = wlan_hdd_cfg80211_resume_wlan,
20126 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020127 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070020128#ifdef WLAN_NL80211_TESTMODE
20129 .testmode_cmd = wlan_hdd_cfg80211_testmode,
20130#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020131 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020132#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20133 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020134 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020135#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020136};
20137