blob: 186c9750719af23d8780e6de5224158a5e9af29c [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Abhishek Singhb3e376c2017-01-04 15:27:13 +05302 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +053099#include "wlan_logging_sock_svc.h"
Agrawal Ashishcfe83282016-09-29 13:03:45 +0530100#include "wlan_hdd_misc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530101
Jeff Johnson295189b2012-06-20 16:38:30 -0700102
103#define g_mode_rates_size (12)
104#define a_mode_rates_size (8)
105#define FREQ_BASE_80211G (2407)
106#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700107#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530108#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800110 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700111
112#define HDD2GHZCHAN(freq, chan, flag) { \
113 .band = IEEE80211_BAND_2GHZ, \
114 .center_freq = (freq), \
115 .hw_value = (chan),\
116 .flags = (flag), \
117 .max_antenna_gain = 0 ,\
118 .max_power = 30, \
119}
120
121#define HDD5GHZCHAN(freq, chan, flag) { \
122 .band = IEEE80211_BAND_5GHZ, \
123 .center_freq = (freq), \
124 .hw_value = (chan),\
125 .flags = (flag), \
126 .max_antenna_gain = 0 ,\
127 .max_power = 30, \
128}
129
130#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
131{\
132 .bitrate = rate, \
133 .hw_value = rate_id, \
134 .flags = flag, \
135}
136
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530137#ifdef WLAN_FEATURE_VOWIFI_11R
138#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
139#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
140#endif
141
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530142#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530143#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530144
Sunil Duttc69bccb2014-05-26 21:30:20 +0530145#ifdef WLAN_FEATURE_LINK_LAYER_STATS
146/*
147 * Used to allocate the size of 4096 for the link layer stats.
148 * The size of 4096 is considered assuming that all data per
149 * respective event fit with in the limit.Please take a call
150 * on the limit based on the data requirements on link layer
151 * statistics.
152 */
153#define LL_STATS_EVENT_BUF_SIZE 4096
154#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530155#ifdef WLAN_FEATURE_EXTSCAN
156/*
157 * Used to allocate the size of 4096 for the EXTScan NL data.
158 * The size of 4096 is considered assuming that all data per
159 * respective event fit with in the limit.Please take a call
160 * on the limit based on the data requirements.
161 */
162
163#define EXTSCAN_EVENT_BUF_SIZE 4096
164#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
165#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530166
Atul Mittal115287b2014-07-08 13:26:33 +0530167/*EXT TDLS*/
168/*
169 * Used to allocate the size of 4096 for the TDLS.
170 * The size of 4096 is considered assuming that all data per
171 * respective event fit with in the limit.Please take a call
172 * on the limit based on the data requirements on link layer
173 * statistics.
174 */
175#define EXTTDLS_EVENT_BUF_SIZE 4096
176
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530177/*
178 * Values for Mac spoofing feature
179 *
180 */
181#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
182#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
183#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530184#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
185
Anurag Chouhan343af7e2016-12-16 13:11:19 +0530186/*
187 * max_sched_scan_plans defined to 10
188 */
189#define MAX_SCHED_SCAN_PLANS 10
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530190
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530191static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700192{
193 WLAN_CIPHER_SUITE_WEP40,
194 WLAN_CIPHER_SUITE_WEP104,
195 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800196#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700197#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
198 WLAN_CIPHER_SUITE_KRK,
199 WLAN_CIPHER_SUITE_CCMP,
200#else
201 WLAN_CIPHER_SUITE_CCMP,
202#endif
203#ifdef FEATURE_WLAN_WAPI
204 WLAN_CIPHER_SUITE_SMS4,
205#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700206#ifdef WLAN_FEATURE_11W
207 WLAN_CIPHER_SUITE_AES_CMAC,
208#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700209};
210
211static inline int is_broadcast_ether_addr(const u8 *addr)
212{
213 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
214 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
215}
216
Agrawal Ashish97dec502015-11-26 20:20:58 +0530217const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530218{
Jeff Johnson295189b2012-06-20 16:38:30 -0700219 HDD2GHZCHAN(2412, 1, 0) ,
220 HDD2GHZCHAN(2417, 2, 0) ,
221 HDD2GHZCHAN(2422, 3, 0) ,
222 HDD2GHZCHAN(2427, 4, 0) ,
223 HDD2GHZCHAN(2432, 5, 0) ,
224 HDD2GHZCHAN(2437, 6, 0) ,
225 HDD2GHZCHAN(2442, 7, 0) ,
226 HDD2GHZCHAN(2447, 8, 0) ,
227 HDD2GHZCHAN(2452, 9, 0) ,
228 HDD2GHZCHAN(2457, 10, 0) ,
229 HDD2GHZCHAN(2462, 11, 0) ,
230 HDD2GHZCHAN(2467, 12, 0) ,
231 HDD2GHZCHAN(2472, 13, 0) ,
232 HDD2GHZCHAN(2484, 14, 0) ,
233};
234
Agrawal Ashish97dec502015-11-26 20:20:58 +0530235const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700236{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700237 HDD5GHZCHAN(4920, 240, 0) ,
238 HDD5GHZCHAN(4940, 244, 0) ,
239 HDD5GHZCHAN(4960, 248, 0) ,
240 HDD5GHZCHAN(4980, 252, 0) ,
241 HDD5GHZCHAN(5040, 208, 0) ,
242 HDD5GHZCHAN(5060, 212, 0) ,
243 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700244 HDD5GHZCHAN(5180, 36, 0) ,
245 HDD5GHZCHAN(5200, 40, 0) ,
246 HDD5GHZCHAN(5220, 44, 0) ,
247 HDD5GHZCHAN(5240, 48, 0) ,
248 HDD5GHZCHAN(5260, 52, 0) ,
249 HDD5GHZCHAN(5280, 56, 0) ,
250 HDD5GHZCHAN(5300, 60, 0) ,
251 HDD5GHZCHAN(5320, 64, 0) ,
252 HDD5GHZCHAN(5500,100, 0) ,
253 HDD5GHZCHAN(5520,104, 0) ,
254 HDD5GHZCHAN(5540,108, 0) ,
255 HDD5GHZCHAN(5560,112, 0) ,
256 HDD5GHZCHAN(5580,116, 0) ,
257 HDD5GHZCHAN(5600,120, 0) ,
258 HDD5GHZCHAN(5620,124, 0) ,
259 HDD5GHZCHAN(5640,128, 0) ,
260 HDD5GHZCHAN(5660,132, 0) ,
261 HDD5GHZCHAN(5680,136, 0) ,
262 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800263#ifdef FEATURE_WLAN_CH144
264 HDD5GHZCHAN(5720,144, 0) ,
265#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700266 HDD5GHZCHAN(5745,149, 0) ,
267 HDD5GHZCHAN(5765,153, 0) ,
268 HDD5GHZCHAN(5785,157, 0) ,
269 HDD5GHZCHAN(5805,161, 0) ,
270 HDD5GHZCHAN(5825,165, 0) ,
271};
272
273static struct ieee80211_rate g_mode_rates[] =
274{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530275 HDD_G_MODE_RATETAB(10, 0x1, 0),
276 HDD_G_MODE_RATETAB(20, 0x2, 0),
277 HDD_G_MODE_RATETAB(55, 0x4, 0),
278 HDD_G_MODE_RATETAB(110, 0x8, 0),
279 HDD_G_MODE_RATETAB(60, 0x10, 0),
280 HDD_G_MODE_RATETAB(90, 0x20, 0),
281 HDD_G_MODE_RATETAB(120, 0x40, 0),
282 HDD_G_MODE_RATETAB(180, 0x80, 0),
283 HDD_G_MODE_RATETAB(240, 0x100, 0),
284 HDD_G_MODE_RATETAB(360, 0x200, 0),
285 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700286 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530287};
Jeff Johnson295189b2012-06-20 16:38:30 -0700288
289static struct ieee80211_rate a_mode_rates[] =
290{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530291 HDD_G_MODE_RATETAB(60, 0x10, 0),
292 HDD_G_MODE_RATETAB(90, 0x20, 0),
293 HDD_G_MODE_RATETAB(120, 0x40, 0),
294 HDD_G_MODE_RATETAB(180, 0x80, 0),
295 HDD_G_MODE_RATETAB(240, 0x100, 0),
296 HDD_G_MODE_RATETAB(360, 0x200, 0),
297 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 HDD_G_MODE_RATETAB(540, 0x800, 0),
299};
300
301static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
302{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530303 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700304 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
305 .band = IEEE80211_BAND_2GHZ,
306 .bitrates = g_mode_rates,
307 .n_bitrates = g_mode_rates_size,
308 .ht_cap.ht_supported = 1,
309 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
310 | IEEE80211_HT_CAP_GRN_FLD
311 | IEEE80211_HT_CAP_DSSSCCK40
312 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
313 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
314 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
315 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
316 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
317 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
318};
319
Jeff Johnson295189b2012-06-20 16:38:30 -0700320static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
321{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530322 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
324 .band = IEEE80211_BAND_5GHZ,
325 .bitrates = a_mode_rates,
326 .n_bitrates = a_mode_rates_size,
327 .ht_cap.ht_supported = 1,
328 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
329 | IEEE80211_HT_CAP_GRN_FLD
330 | IEEE80211_HT_CAP_DSSSCCK40
331 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
332 | IEEE80211_HT_CAP_SGI_40
333 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
334 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
335 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
336 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
337 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
338 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
339};
340
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530341/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700342 TX/RX direction for each kind of interface */
343static const struct ieee80211_txrx_stypes
344wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
345 [NL80211_IFTYPE_STATION] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ACTION) |
348 BIT(SIR_MAC_MGMT_PROBE_REQ),
349 },
350 [NL80211_IFTYPE_AP] = {
351 .tx = 0xffff,
352 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
353 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
354 BIT(SIR_MAC_MGMT_PROBE_REQ) |
355 BIT(SIR_MAC_MGMT_DISASSOC) |
356 BIT(SIR_MAC_MGMT_AUTH) |
357 BIT(SIR_MAC_MGMT_DEAUTH) |
358 BIT(SIR_MAC_MGMT_ACTION),
359 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700360 [NL80211_IFTYPE_ADHOC] = {
361 .tx = 0xffff,
362 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
363 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
364 BIT(SIR_MAC_MGMT_PROBE_REQ) |
365 BIT(SIR_MAC_MGMT_DISASSOC) |
366 BIT(SIR_MAC_MGMT_AUTH) |
367 BIT(SIR_MAC_MGMT_DEAUTH) |
368 BIT(SIR_MAC_MGMT_ACTION),
369 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700370 [NL80211_IFTYPE_P2P_CLIENT] = {
371 .tx = 0xffff,
372 .rx = BIT(SIR_MAC_MGMT_ACTION) |
373 BIT(SIR_MAC_MGMT_PROBE_REQ),
374 },
375 [NL80211_IFTYPE_P2P_GO] = {
376 /* This is also same as for SoftAP */
377 .tx = 0xffff,
378 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
379 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
380 BIT(SIR_MAC_MGMT_PROBE_REQ) |
381 BIT(SIR_MAC_MGMT_DISASSOC) |
382 BIT(SIR_MAC_MGMT_AUTH) |
383 BIT(SIR_MAC_MGMT_DEAUTH) |
384 BIT(SIR_MAC_MGMT_ACTION),
385 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700386};
387
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800388#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800389static const struct ieee80211_iface_limit
390wlan_hdd_iface_limit[] = {
391 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800392 /* max = 3 ; Our driver create two interfaces during driver init
393 * wlan0 and p2p0 interfaces. p2p0 is considered as station
394 * interface until a group is formed. In JB architecture, once the
395 * group is formed, interface type of p2p0 is changed to P2P GO or
396 * Client.
397 * When supplicant remove the group, it first issue a set interface
398 * cmd to change the mode back to Station. In JB this works fine as
399 * we advertize two station type interface during driver init.
400 * Some vendors create separate interface for P2P GO/Client,
401 * after group formation(Third one). But while group remove
402 * supplicant first tries to change the mode(3rd interface) to STATION
403 * But as we advertized only two sta type interfaces nl80211 was
404 * returning error for the third one which was leading to failure in
405 * delete interface. Ideally while removing the group, supplicant
406 * should not try to change the 3rd interface mode to Station type.
407 * Till we get a fix in wpa_supplicant, we advertize max STA
408 * interface type to 3
409 */
410 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 .types = BIT(NL80211_IFTYPE_STATION),
412 },
413 {
414 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700415 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800416 },
417 {
418 .max = 1,
419 .types = BIT(NL80211_IFTYPE_P2P_GO) |
420 BIT(NL80211_IFTYPE_P2P_CLIENT),
421 },
422};
423
424/* By default, only single channel concurrency is allowed */
425static struct ieee80211_iface_combination
426wlan_hdd_iface_combination = {
427 .limits = wlan_hdd_iface_limit,
428 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800429 /*
430 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
431 * and p2p0 interfaces during driver init
432 * Some vendors create separate interface for P2P operations.
433 * wlan0: STA interface
434 * p2p0: P2P Device interface, action frames goes
435 * through this interface.
436 * p2p-xx: P2P interface, After GO negotiation this interface is
437 * created for p2p operations(GO/CLIENT interface).
438 */
439 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800440 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
441 .beacon_int_infra_match = false,
442};
443#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800444
Jeff Johnson295189b2012-06-20 16:38:30 -0700445static struct cfg80211_ops wlan_hdd_cfg80211_ops;
446
447/* Data rate 100KBPS based on IE Index */
448struct index_data_rate_type
449{
450 v_U8_t beacon_rate_index;
451 v_U16_t supported_rate[4];
452};
453
454/* 11B, 11G Rate table include Basic rate and Extended rate
455 The IDX field is the rate index
456 The HI field is the rate when RSSI is strong or being ignored
457 (in this case we report actual rate)
458 The MID field is the rate when RSSI is moderate
459 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
460 The LO field is the rate when RSSI is low
461 (in this case we don't report rates, actual current rate used)
462 */
463static const struct
464{
465 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700466 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700467} supported_data_rate[] =
468{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700469/* IDX HI HM LM LO (RSSI-based index */
470 {2, { 10, 10, 10, 0}},
471 {4, { 20, 20, 10, 0}},
472 {11, { 55, 20, 10, 0}},
473 {12, { 60, 55, 20, 0}},
474 {18, { 90, 55, 20, 0}},
475 {22, {110, 55, 20, 0}},
476 {24, {120, 90, 60, 0}},
477 {36, {180, 120, 60, 0}},
478 {44, {220, 180, 60, 0}},
479 {48, {240, 180, 90, 0}},
480 {66, {330, 180, 90, 0}},
481 {72, {360, 240, 90, 0}},
482 {96, {480, 240, 120, 0}},
483 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700484};
485
486/* MCS Based rate table */
487static struct index_data_rate_type supported_mcs_rate[] =
488{
489/* MCS L20 L40 S20 S40 */
490 {0, {65, 135, 72, 150}},
491 {1, {130, 270, 144, 300}},
492 {2, {195, 405, 217, 450}},
493 {3, {260, 540, 289, 600}},
494 {4, {390, 810, 433, 900}},
495 {5, {520, 1080, 578, 1200}},
496 {6, {585, 1215, 650, 1350}},
497 {7, {650, 1350, 722, 1500}}
498};
499
Leo Chang6f8870f2013-03-26 18:11:36 -0700500#ifdef WLAN_FEATURE_11AC
501
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530502#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700503
504struct index_vht_data_rate_type
505{
506 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530507 v_U16_t supported_VHT80_rate[2];
508 v_U16_t supported_VHT40_rate[2];
509 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700510};
511
512typedef enum
513{
514 DATA_RATE_11AC_MAX_MCS_7,
515 DATA_RATE_11AC_MAX_MCS_8,
516 DATA_RATE_11AC_MAX_MCS_9,
517 DATA_RATE_11AC_MAX_MCS_NA
518} eDataRate11ACMaxMcs;
519
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530520/* SSID broadcast type */
521typedef enum eSSIDBcastType
522{
523 eBCAST_UNKNOWN = 0,
524 eBCAST_NORMAL = 1,
525 eBCAST_HIDDEN = 2,
526} tSSIDBcastType;
527
Leo Chang6f8870f2013-03-26 18:11:36 -0700528/* MCS Based VHT rate table */
529static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
530{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530531/* MCS L80 S80 L40 S40 L20 S40*/
532 {0, {293, 325}, {135, 150}, {65, 72}},
533 {1, {585, 650}, {270, 300}, {130, 144}},
534 {2, {878, 975}, {405, 450}, {195, 217}},
535 {3, {1170, 1300}, {540, 600}, {260, 289}},
536 {4, {1755, 1950}, {810, 900}, {390, 433}},
537 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
538 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
539 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
540 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
541 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700542};
543#endif /* WLAN_FEATURE_11AC */
544
c_hpothu79aab322014-07-14 21:11:01 +0530545/*array index points to MCS and array value points respective rssi*/
546static int rssiMcsTbl[][10] =
547{
548/*MCS 0 1 2 3 4 5 6 7 8 9*/
549 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
550 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
551 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
552};
553
Jeff Johnson295189b2012-06-20 16:38:30 -0700554extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530555#ifdef FEATURE_WLAN_SCAN_PNO
556static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
557#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700558
Leo Chang9056f462013-08-01 19:21:11 -0700559#ifdef WLAN_NL80211_TESTMODE
560enum wlan_hdd_tm_attr
561{
562 WLAN_HDD_TM_ATTR_INVALID = 0,
563 WLAN_HDD_TM_ATTR_CMD = 1,
564 WLAN_HDD_TM_ATTR_DATA = 2,
565 WLAN_HDD_TM_ATTR_TYPE = 3,
566 /* keep last */
567 WLAN_HDD_TM_ATTR_AFTER_LAST,
568 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
569};
570
571enum wlan_hdd_tm_cmd
572{
573 WLAN_HDD_TM_CMD_WLAN_HB = 1,
574};
575
576#define WLAN_HDD_TM_DATA_MAX_LEN 5000
577
578static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
579{
580 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
581 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
582 .len = WLAN_HDD_TM_DATA_MAX_LEN },
583};
584#endif /* WLAN_NL80211_TESTMODE */
585
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800586#ifdef FEATURE_WLAN_CH_AVOID
587/*
588 * FUNCTION: wlan_hdd_send_avoid_freq_event
589 * This is called when wlan driver needs to send vendor specific
590 * avoid frequency range event to userspace
591 */
592int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
593 tHddAvoidFreqList *pAvoidFreqList)
594{
595 struct sk_buff *vendor_event;
596
597 ENTER();
598
599 if (!pHddCtx)
600 {
601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
602 "%s: HDD context is null", __func__);
603 return -1;
604 }
605
606 if (!pAvoidFreqList)
607 {
608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
609 "%s: pAvoidFreqList is null", __func__);
610 return -1;
611 }
612
613 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530614#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
615 NULL,
616#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800617 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530618 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800619 GFP_KERNEL);
620 if (!vendor_event)
621 {
622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
623 "%s: cfg80211_vendor_event_alloc failed", __func__);
624 return -1;
625 }
626
627 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
628 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
629
630 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
631
632 EXIT();
633 return 0;
634}
635#endif /* FEATURE_WLAN_CH_AVOID */
636
Srinivas Dasari030bad32015-02-18 23:23:54 +0530637/*
638 * FUNCTION: __wlan_hdd_cfg80211_nan_request
639 * This is called when wlan driver needs to send vendor specific
640 * nan request event.
641 */
642static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
643 struct wireless_dev *wdev,
644 const void *data, int data_len)
645{
646 tNanRequestReq nan_req;
647 VOS_STATUS status;
648 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530649 struct net_device *dev = wdev->netdev;
650 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
651 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530652 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
653
654 if (0 == data_len)
655 {
656 hddLog(VOS_TRACE_LEVEL_ERROR,
657 FL("NAN - Invalid Request, length = 0"));
658 return ret_val;
659 }
660
661 if (NULL == data)
662 {
663 hddLog(VOS_TRACE_LEVEL_ERROR,
664 FL("NAN - Invalid Request, data is NULL"));
665 return ret_val;
666 }
667
668 status = wlan_hdd_validate_context(pHddCtx);
669 if (0 != status)
670 {
671 hddLog(VOS_TRACE_LEVEL_ERROR,
672 FL("HDD context is not valid"));
673 return -EINVAL;
674 }
675
676 hddLog(LOG1, FL("Received NAN command"));
677 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
678 (tANI_U8 *)data, data_len);
679
680 /* check the NAN Capability */
681 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
682 {
683 hddLog(VOS_TRACE_LEVEL_ERROR,
684 FL("NAN is not supported by Firmware"));
685 return -EINVAL;
686 }
687
688 nan_req.request_data_len = data_len;
689 nan_req.request_data = data;
690
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530691 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530692 if (VOS_STATUS_SUCCESS == status)
693 {
694 ret_val = 0;
695 }
696 return ret_val;
697}
698
699/*
700 * FUNCTION: wlan_hdd_cfg80211_nan_request
701 * Wrapper to protect the nan vendor command from ssr
702 */
703static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
704 struct wireless_dev *wdev,
705 const void *data, int data_len)
706{
707 int ret;
708
709 vos_ssr_protect(__func__);
710 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
711 vos_ssr_unprotect(__func__);
712
713 return ret;
714}
715
716/*
717 * FUNCTION: wlan_hdd_cfg80211_nan_callback
718 * This is a callback function and it gets called
719 * when we need to report nan response event to
720 * upper layers.
721 */
722static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
723{
724 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
725 struct sk_buff *vendor_event;
726 int status;
727 tSirNanEvent *data;
728
729 ENTER();
730 if (NULL == msg)
731 {
732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
733 FL(" msg received here is null"));
734 return;
735 }
736 data = msg;
737
738 status = wlan_hdd_validate_context(pHddCtx);
739
740 if (0 != status)
741 {
742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
743 FL("HDD context is not valid"));
744 return;
745 }
746
747 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530748#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
749 NULL,
750#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530751 data->event_data_len +
752 NLMSG_HDRLEN,
753 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
754 GFP_KERNEL);
755
756 if (!vendor_event)
757 {
758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
759 FL("cfg80211_vendor_event_alloc failed"));
760 return;
761 }
762 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
763 data->event_data_len, data->event_data))
764 {
765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
766 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
767 kfree_skb(vendor_event);
768 return;
769 }
770 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
771 EXIT();
772}
773
774/*
775 * FUNCTION: wlan_hdd_cfg80211_nan_init
776 * This function is called to register the callback to sme layer
777 */
778inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
779{
780 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
781}
782
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530783/*
784 * define short names for the global vendor params
785 * used by __wlan_hdd_cfg80211_get_station_cmd()
786 */
787#define STATION_INVALID \
788 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
789#define STATION_INFO \
790 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
791#define STATION_ASSOC_FAIL_REASON \
792 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
793#define STATION_MAX \
794 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
795
796static const struct nla_policy
797hdd_get_station_policy[STATION_MAX + 1] = {
798 [STATION_INFO] = {.type = NLA_FLAG},
799 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
800};
801
802/**
803 * hdd_get_station_assoc_fail() - Handle get station assoc fail
804 * @hdd_ctx: HDD context within host driver
805 * @wdev: wireless device
806 *
807 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
808 * Validate cmd attributes and send the station info to upper layers.
809 *
810 * Return: Success(0) or reason code for failure
811 */
812static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
813 hdd_adapter_t *adapter)
814{
815 struct sk_buff *skb = NULL;
816 uint32_t nl_buf_len;
817 hdd_station_ctx_t *hdd_sta_ctx;
818
819 nl_buf_len = NLMSG_HDRLEN;
820 nl_buf_len += sizeof(uint32_t);
821 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
822
823 if (!skb) {
824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
825 return -ENOMEM;
826 }
827
828 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
829
830 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
831 hdd_sta_ctx->conn_info.assoc_status_code)) {
832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
833 goto fail;
834 }
835 return cfg80211_vendor_cmd_reply(skb);
836fail:
837 if (skb)
838 kfree_skb(skb);
839 return -EINVAL;
840}
841
842/**
843 * hdd_map_auth_type() - transform auth type specific to
844 * vendor command
845 * @auth_type: csr auth type
846 *
847 * Return: Success(0) or reason code for failure
848 */
849static int hdd_convert_auth_type(uint32_t auth_type)
850{
851 uint32_t ret_val;
852
853 switch (auth_type) {
854 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
855 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
856 break;
857 case eCSR_AUTH_TYPE_SHARED_KEY:
858 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
859 break;
860 case eCSR_AUTH_TYPE_WPA:
861 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
862 break;
863 case eCSR_AUTH_TYPE_WPA_PSK:
864 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
865 break;
866 case eCSR_AUTH_TYPE_AUTOSWITCH:
867 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
868 break;
869 case eCSR_AUTH_TYPE_WPA_NONE:
870 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
871 break;
872 case eCSR_AUTH_TYPE_RSN:
873 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
874 break;
875 case eCSR_AUTH_TYPE_RSN_PSK:
876 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
877 break;
878 case eCSR_AUTH_TYPE_FT_RSN:
879 ret_val = QCA_WLAN_AUTH_TYPE_FT;
880 break;
881 case eCSR_AUTH_TYPE_FT_RSN_PSK:
882 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
883 break;
884 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
885 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
886 break;
887 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
888 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
889 break;
890#ifdef FEATURE_WLAN_ESE
891 case eCSR_AUTH_TYPE_CCKM_WPA:
892 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
893 break;
894 case eCSR_AUTH_TYPE_CCKM_RSN:
895 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
896 break;
897#endif
898 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
899 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
900 break;
901 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
902 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
903 break;
904 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
905 case eCSR_AUTH_TYPE_FAILED:
906 case eCSR_AUTH_TYPE_NONE:
907 default:
908 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
909 break;
910 }
911 return ret_val;
912}
913
914/**
915 * hdd_map_dot_11_mode() - transform dot11mode type specific to
916 * vendor command
917 * @dot11mode: dot11mode
918 *
919 * Return: Success(0) or reason code for failure
920 */
921static int hdd_convert_dot11mode(uint32_t dot11mode)
922{
923 uint32_t ret_val;
924
925 switch (dot11mode) {
926 case eCSR_CFG_DOT11_MODE_11A:
927 ret_val = QCA_WLAN_802_11_MODE_11A;
928 break;
929 case eCSR_CFG_DOT11_MODE_11B:
930 ret_val = QCA_WLAN_802_11_MODE_11B;
931 break;
932 case eCSR_CFG_DOT11_MODE_11G:
933 ret_val = QCA_WLAN_802_11_MODE_11G;
934 break;
935 case eCSR_CFG_DOT11_MODE_11N:
936 ret_val = QCA_WLAN_802_11_MODE_11N;
937 break;
938 case eCSR_CFG_DOT11_MODE_11AC:
939 ret_val = QCA_WLAN_802_11_MODE_11AC;
940 break;
941 case eCSR_CFG_DOT11_MODE_AUTO:
942 case eCSR_CFG_DOT11_MODE_ABG:
943 default:
944 ret_val = QCA_WLAN_802_11_MODE_INVALID;
945 }
946 return ret_val;
947}
948
949/**
950 * hdd_add_tx_bitrate() - add tx bitrate attribute
951 * @skb: pointer to sk buff
952 * @hdd_sta_ctx: pointer to hdd station context
953 * @idx: attribute index
954 *
955 * Return: Success(0) or reason code for failure
956 */
957static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
958 hdd_station_ctx_t *hdd_sta_ctx,
959 int idx)
960{
961 struct nlattr *nla_attr;
962 uint32_t bitrate, bitrate_compat;
963
964 nla_attr = nla_nest_start(skb, idx);
965 if (!nla_attr)
966 goto fail;
967 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
968 bitrate = cfg80211_calculate_bitrate(&hdd_sta_ctx->conn_info.txrate);
969
970 /* report 16-bit bitrate only if we can */
971 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
972 if (bitrate > 0 &&
973 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
974 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
975 goto fail;
976 }
977 if (bitrate_compat > 0 &&
978 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
979 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
980 goto fail;
981 }
982 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
983 hdd_sta_ctx->conn_info.txrate.nss)) {
984 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
985 goto fail;
986 }
987 nla_nest_end(skb, nla_attr);
988 return 0;
989fail:
990 return -EINVAL;
991}
992
993/**
994 * hdd_add_sta_info() - add station info attribute
995 * @skb: pointer to sk buff
996 * @hdd_sta_ctx: pointer to hdd station context
997 * @idx: attribute index
998 *
999 * Return: Success(0) or reason code for failure
1000 */
1001static int32_t hdd_add_sta_info(struct sk_buff *skb,
1002 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1003{
1004 struct nlattr *nla_attr;
1005
1006 nla_attr = nla_nest_start(skb, idx);
1007 if (!nla_attr)
1008 goto fail;
1009 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
1010 (hdd_sta_ctx->conn_info.signal + 100))) {
1011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1012 goto fail;
1013 }
1014 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1015 goto fail;
1016 nla_nest_end(skb, nla_attr);
1017 return 0;
1018fail:
1019 return -EINVAL;
1020}
1021
1022/**
1023 * hdd_add_survey_info() - add survey info attribute
1024 * @skb: pointer to sk buff
1025 * @hdd_sta_ctx: pointer to hdd station context
1026 * @idx: attribute index
1027 *
1028 * Return: Success(0) or reason code for failure
1029 */
1030static int32_t hdd_add_survey_info(struct sk_buff *skb,
1031 hdd_station_ctx_t *hdd_sta_ctx,
1032 int idx)
1033{
1034 struct nlattr *nla_attr;
1035
1036 nla_attr = nla_nest_start(skb, idx);
1037 if (!nla_attr)
1038 goto fail;
1039 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1040 hdd_sta_ctx->conn_info.freq) ||
1041 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
1042 (hdd_sta_ctx->conn_info.noise + 100))) {
1043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1044 goto fail;
1045 }
1046 nla_nest_end(skb, nla_attr);
1047 return 0;
1048fail:
1049 return -EINVAL;
1050}
1051
1052/**
1053 * hdd_add_link_standard_info() - add link info attribute
1054 * @skb: pointer to sk buff
1055 * @hdd_sta_ctx: pointer to hdd station context
1056 * @idx: attribute index
1057 *
1058 * Return: Success(0) or reason code for failure
1059 */
1060static int32_t
1061hdd_add_link_standard_info(struct sk_buff *skb,
1062 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1063{
1064 struct nlattr *nla_attr;
1065
1066 nla_attr = nla_nest_start(skb, idx);
1067 if (!nla_attr)
1068 goto fail;
1069 if (nla_put(skb,
1070 NL80211_ATTR_SSID,
1071 hdd_sta_ctx->conn_info.SSID.SSID.length,
1072 hdd_sta_ctx->conn_info.SSID.SSID.ssId)) {
1073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1074 goto fail;
1075 }
1076 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1077 goto fail;
1078 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1079 goto fail;
1080 nla_nest_end(skb, nla_attr);
1081 return 0;
1082fail:
1083 return -EINVAL;
1084}
1085
1086/**
1087 * hdd_add_ap_standard_info() - add ap info attribute
1088 * @skb: pointer to sk buff
1089 * @hdd_sta_ctx: pointer to hdd station context
1090 * @idx: attribute index
1091 *
1092 * Return: Success(0) or reason code for failure
1093 */
1094static int32_t
1095hdd_add_ap_standard_info(struct sk_buff *skb,
1096 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1097{
1098 struct nlattr *nla_attr;
1099
1100 nla_attr = nla_nest_start(skb, idx);
1101 if (!nla_attr)
1102 goto fail;
1103 if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
1104 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1105 sizeof(hdd_sta_ctx->conn_info.vht_caps),
1106 &hdd_sta_ctx->conn_info.vht_caps)) {
1107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1108 goto fail;
1109 }
1110 if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
1111 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1112 sizeof(hdd_sta_ctx->conn_info.ht_caps),
1113 &hdd_sta_ctx->conn_info.ht_caps)) {
1114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1115 goto fail;
1116 }
1117 nla_nest_end(skb, nla_attr);
1118 return 0;
1119fail:
1120 return -EINVAL;
1121}
1122
1123/**
1124 * hdd_get_station_info() - send BSS information to supplicant
1125 * @hdd_ctx: pointer to hdd context
1126 * @adapter: pointer to adapter
1127 *
1128 * Return: 0 if success else error status
1129 */
1130static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1131 hdd_adapter_t *adapter)
1132{
1133 struct sk_buff *skb = NULL;
1134 uint8_t *tmp_hs20 = NULL;
1135 uint32_t nl_buf_len;
1136 hdd_station_ctx_t *hdd_sta_ctx;
1137
1138 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1139
1140 nl_buf_len = NLMSG_HDRLEN;
1141 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.SSID.SSID.length) +
1142 sizeof(hdd_sta_ctx->conn_info.freq) +
1143 sizeof(hdd_sta_ctx->conn_info.noise) +
1144 sizeof(hdd_sta_ctx->conn_info.signal) +
1145 (sizeof(uint32_t) * 2) +
1146 sizeof(hdd_sta_ctx->conn_info.txrate.nss) +
1147 sizeof(hdd_sta_ctx->conn_info.roam_count) +
1148 sizeof(hdd_sta_ctx->conn_info.authType) +
1149 sizeof(hdd_sta_ctx->conn_info.dot11Mode);
1150 if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
1151 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_caps);
1152 if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
1153 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_caps);
1154 if (hdd_sta_ctx->conn_info.conn_flag.hs20_present) {
1155 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->conn_info.hs20vendor_ie);
1156 nl_buf_len += (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) -
1157 1);
1158 }
1159 if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
1160 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_operation);
1161 if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
1162 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_operation);
1163
1164
1165 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1166 if (!skb) {
1167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1168 __func__, __LINE__);
1169 return -ENOMEM;
1170 }
1171
1172 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1173 LINK_INFO_STANDARD_NL80211_ATTR)) {
1174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1175 goto fail;
1176 }
1177 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1178 AP_INFO_STANDARD_NL80211_ATTR)) {
1179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1180 goto fail;
1181 }
1182 if (nla_put_u32(skb, INFO_ROAM_COUNT,
1183 hdd_sta_ctx->conn_info.roam_count) ||
1184 nla_put_u32(skb, INFO_AKM,
1185 hdd_convert_auth_type(
1186 hdd_sta_ctx->conn_info.authType)) ||
1187 nla_put_u32(skb, WLAN802_11_MODE,
1188 hdd_convert_dot11mode(
1189 hdd_sta_ctx->conn_info.dot11Mode))) {
1190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1191 goto fail;
1192 }
1193 if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
1194 if (nla_put(skb, HT_OPERATION,
1195 (sizeof(hdd_sta_ctx->conn_info.ht_operation)),
1196 &hdd_sta_ctx->conn_info.ht_operation)) {
1197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1198 goto fail;
1199 }
1200 if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
1201 if (nla_put(skb, VHT_OPERATION,
1202 (sizeof(hdd_sta_ctx->conn_info.vht_operation)),
1203 &hdd_sta_ctx->conn_info.vht_operation)) {
1204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1205 goto fail;
1206 }
1207 if (hdd_sta_ctx->conn_info.conn_flag.hs20_present)
1208 if (nla_put(skb, AP_INFO_HS20_INDICATION,
1209 (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) - 1),
1210 tmp_hs20 + 1)) {
1211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1212 goto fail;
1213 }
1214
1215 return cfg80211_vendor_cmd_reply(skb);
1216fail:
1217 if (skb)
1218 kfree_skb(skb);
1219 return -EINVAL;
1220}
1221
1222/**
1223 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1224 * @wiphy: corestack handler
1225 * @wdev: wireless device
1226 * @data: data
1227 * @data_len: data length
1228 *
1229 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1230 * Validate cmd attributes and send the station info to upper layers.
1231 *
1232 * Return: Success(0) or reason code for failure
1233 */
1234static int32_t
1235__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1236 struct wireless_dev *wdev,
1237 const void *data,
1238 int data_len)
1239{
1240 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1241 struct net_device *dev = wdev->netdev;
1242 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1243 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1244 int32_t status;
1245
1246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1247 if (VOS_FTM_MODE == hdd_get_conparam()) {
1248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1249 status = -EPERM;
1250 goto out;
1251 }
1252
1253 status = wlan_hdd_validate_context(hdd_ctx);
1254 if (0 != status)
1255 goto out;
1256
1257
1258 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1259 data, data_len, NULL);
1260 if (status) {
1261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1262 goto out;
1263 }
1264
1265 /* Parse and fetch Command Type*/
1266 if (tb[STATION_INFO]) {
1267 status = hdd_get_station_info(hdd_ctx, adapter);
1268 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1269 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
1270 } else {
1271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1272 status = -EINVAL;
1273 goto out;
1274 }
1275 EXIT();
1276out:
1277 return status;
1278}
1279
1280/**
1281 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1282 * @wiphy: corestack handler
1283 * @wdev: wireless device
1284 * @data: data
1285 * @data_len: data length
1286 *
1287 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1288 * Validate cmd attributes and send the station info to upper layers.
1289 *
1290 * Return: Success(0) or reason code for failure
1291 */
1292static int32_t
1293hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1294 struct wireless_dev *wdev,
1295 const void *data,
1296 int data_len)
1297{
1298 int ret;
1299
1300 vos_ssr_protect(__func__);
1301 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1302 vos_ssr_unprotect(__func__);
1303
1304 return ret;
1305}
1306
1307/*
1308 * undef short names defined for get station command
1309 * used by __wlan_hdd_cfg80211_get_station_cmd()
1310 */
1311#undef STATION_INVALID
1312#undef STATION_INFO
1313#undef STATION_ASSOC_FAIL_REASON
1314#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301315
Sunil Duttc69bccb2014-05-26 21:30:20 +05301316#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1317
1318static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1319 struct sk_buff *vendor_event)
1320{
1321 if (nla_put_u8(vendor_event,
1322 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1323 stats->rate.preamble) ||
1324 nla_put_u8(vendor_event,
1325 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1326 stats->rate.nss) ||
1327 nla_put_u8(vendor_event,
1328 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1329 stats->rate.bw) ||
1330 nla_put_u8(vendor_event,
1331 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1332 stats->rate.rateMcsIdx) ||
1333 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1334 stats->rate.bitrate ) ||
1335 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1336 stats->txMpdu ) ||
1337 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1338 stats->rxMpdu ) ||
1339 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1340 stats->mpduLost ) ||
1341 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1342 stats->retries) ||
1343 nla_put_u32(vendor_event,
1344 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1345 stats->retriesShort ) ||
1346 nla_put_u32(vendor_event,
1347 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1348 stats->retriesLong))
1349 {
1350 hddLog(VOS_TRACE_LEVEL_ERROR,
1351 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1352 return FALSE;
1353 }
1354 return TRUE;
1355}
1356
1357static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1358 struct sk_buff *vendor_event)
1359{
1360 u32 i = 0;
1361 struct nlattr *rateInfo;
1362 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1363 stats->type) ||
1364 nla_put(vendor_event,
1365 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1366 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1367 nla_put_u32(vendor_event,
1368 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1369 stats->capabilities) ||
1370 nla_put_u32(vendor_event,
1371 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1372 stats->numRate))
1373 {
1374 hddLog(VOS_TRACE_LEVEL_ERROR,
1375 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1376 goto error;
1377 }
1378
1379 rateInfo = nla_nest_start(vendor_event,
1380 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301381 if(!rateInfo)
1382 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301383 for (i = 0; i < stats->numRate; i++)
1384 {
1385 struct nlattr *rates;
1386 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1387 stats->rateStats +
1388 (i * sizeof(tSirWifiRateStat)));
1389 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301390 if(!rates)
1391 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301392
1393 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1394 {
1395 hddLog(VOS_TRACE_LEVEL_ERROR,
1396 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1397 return FALSE;
1398 }
1399 nla_nest_end(vendor_event, rates);
1400 }
1401 nla_nest_end(vendor_event, rateInfo);
1402
1403 return TRUE;
1404error:
1405 return FALSE;
1406}
1407
1408static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1409 struct sk_buff *vendor_event)
1410{
1411 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1412 stats->ac ) ||
1413 nla_put_u32(vendor_event,
1414 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1415 stats->txMpdu ) ||
1416 nla_put_u32(vendor_event,
1417 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1418 stats->rxMpdu ) ||
1419 nla_put_u32(vendor_event,
1420 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1421 stats->txMcast ) ||
1422 nla_put_u32(vendor_event,
1423 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1424 stats->rxMcast ) ||
1425 nla_put_u32(vendor_event,
1426 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1427 stats->rxAmpdu ) ||
1428 nla_put_u32(vendor_event,
1429 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1430 stats->txAmpdu ) ||
1431 nla_put_u32(vendor_event,
1432 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1433 stats->mpduLost )||
1434 nla_put_u32(vendor_event,
1435 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1436 stats->retries ) ||
1437 nla_put_u32(vendor_event,
1438 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1439 stats->retriesShort ) ||
1440 nla_put_u32(vendor_event,
1441 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1442 stats->retriesLong ) ||
1443 nla_put_u32(vendor_event,
1444 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1445 stats->contentionTimeMin ) ||
1446 nla_put_u32(vendor_event,
1447 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1448 stats->contentionTimeMax ) ||
1449 nla_put_u32(vendor_event,
1450 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1451 stats->contentionTimeAvg ) ||
1452 nla_put_u32(vendor_event,
1453 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1454 stats->contentionNumSamples ))
1455 {
1456 hddLog(VOS_TRACE_LEVEL_ERROR,
1457 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1458 return FALSE;
1459 }
1460 return TRUE;
1461}
1462
1463static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1464 struct sk_buff *vendor_event)
1465{
Dino Myclec8f3f332014-07-21 16:48:27 +05301466 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301467 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1468 nla_put(vendor_event,
1469 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
1470 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
1471 nla_put_u32(vendor_event,
1472 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
1473 stats->state ) ||
1474 nla_put_u32(vendor_event,
1475 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
1476 stats->roaming ) ||
1477 nla_put_u32(vendor_event,
1478 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
1479 stats->capabilities ) ||
1480 nla_put(vendor_event,
1481 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
1482 strlen(stats->ssid), stats->ssid) ||
1483 nla_put(vendor_event,
1484 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
1485 WNI_CFG_BSSID_LEN, stats->bssid) ||
1486 nla_put(vendor_event,
1487 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
1488 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
1489 nla_put(vendor_event,
1490 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
1491 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
1492 )
1493 {
1494 hddLog(VOS_TRACE_LEVEL_ERROR,
1495 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1496 return FALSE;
1497 }
1498 return TRUE;
1499}
1500
Dino Mycle3b9536d2014-07-09 22:05:24 +05301501static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
1502 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301503 struct sk_buff *vendor_event)
1504{
1505 int i = 0;
1506 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301507 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1508 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301509 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301510
Sunil Duttc69bccb2014-05-26 21:30:20 +05301511 if (FALSE == put_wifi_interface_info(
1512 &pWifiIfaceStat->info,
1513 vendor_event))
1514 {
1515 hddLog(VOS_TRACE_LEVEL_ERROR,
1516 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1517 return FALSE;
1518
1519 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05301520 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
1521 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
1522 if (NULL == pWifiIfaceStatTL)
1523 {
1524 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1525 return FALSE;
1526 }
1527
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301528 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1529 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1530 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1531 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1532
1533 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1534 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1535 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1536 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301537
1538 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1539 {
1540 if (VOS_STATUS_SUCCESS ==
1541 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1542 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1543 {
1544 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1545 * obtained from TL structure
1546 */
1547
1548 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1549 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301550 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1551
Srinivas Dasari98947432014-11-07 19:41:24 +05301552 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1553 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1554 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1555 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1556 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1557 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1558 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1559 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301560
Srinivas Dasari98947432014-11-07 19:41:24 +05301561 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1562 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1563 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1564 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1565 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1566 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1567 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1568 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301569
Srinivas Dasari98947432014-11-07 19:41:24 +05301570 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1571 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1572 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1573 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1574 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1575 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1576 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1577 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301578 }
1579 else
1580 {
1581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1582 }
1583
Dino Mycle3b9536d2014-07-09 22:05:24 +05301584 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1585 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1586 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1587 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1588 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1589 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1590 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1591 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1592 }
1593 else
1594 {
1595 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1596 }
1597
1598
Sunil Duttc69bccb2014-05-26 21:30:20 +05301599
1600 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301601 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1602 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1603 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301604 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1605 pWifiIfaceStat->beaconRx) ||
1606 nla_put_u32(vendor_event,
1607 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1608 pWifiIfaceStat->mgmtRx) ||
1609 nla_put_u32(vendor_event,
1610 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1611 pWifiIfaceStat->mgmtActionRx) ||
1612 nla_put_u32(vendor_event,
1613 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1614 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301615 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301616 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1617 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301618 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301619 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1620 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301621 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301622 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1623 pWifiIfaceStat->rssiAck))
1624 {
1625 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301626 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1627 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301628 return FALSE;
1629 }
1630
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301631#ifdef FEATURE_EXT_LL_STAT
1632 /*
1633 * Ensure when EXT_LL_STAT is supported by both host and fwr,
1634 * then host should send Leaky AP stats to upper layer,
1635 * otherwise no need to send these stats.
1636 */
1637 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
1638 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
1639 )
1640 {
1641 hddLog(VOS_TRACE_LEVEL_INFO,
1642 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
1643 pWifiIfaceStat->leakyApStat.is_leaky_ap,
1644 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
1645 pWifiIfaceStat->leakyApStat.rx_leak_window,
1646 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
1647 if (nla_put_u32(vendor_event,
1648 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
1649 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
1650 nla_put_u32(vendor_event,
1651 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
1652 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
1653 nla_put_u32(vendor_event,
1654 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
1655 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
1656 nla_put_u64(vendor_event,
1657 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
1658 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
1659 {
1660 hddLog(VOS_TRACE_LEVEL_ERROR,
1661 FL("EXT_LL_STAT put fail"));
1662 vos_mem_free(pWifiIfaceStatTL);
1663 return FALSE;
1664 }
1665 }
1666#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301667 wmmInfo = nla_nest_start(vendor_event,
1668 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301669 if(!wmmInfo)
1670 {
1671 vos_mem_free(pWifiIfaceStatTL);
1672 return FALSE;
1673 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301674 for (i = 0; i < WIFI_AC_MAX; i++)
1675 {
1676 struct nlattr *wmmStats;
1677 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301678 if(!wmmStats)
1679 {
1680 vos_mem_free(pWifiIfaceStatTL);
1681 return FALSE;
1682 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301683 if (FALSE == put_wifi_wmm_ac_stat(
1684 &pWifiIfaceStat->AccessclassStats[i],
1685 vendor_event))
1686 {
1687 hddLog(VOS_TRACE_LEVEL_ERROR,
1688 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301689 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301690 return FALSE;
1691 }
1692
1693 nla_nest_end(vendor_event, wmmStats);
1694 }
1695 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301696 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301697 return TRUE;
1698}
1699
1700static tSirWifiInterfaceMode
1701 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1702{
1703 switch (deviceMode)
1704 {
1705 case WLAN_HDD_INFRA_STATION:
1706 return WIFI_INTERFACE_STA;
1707 case WLAN_HDD_SOFTAP:
1708 return WIFI_INTERFACE_SOFTAP;
1709 case WLAN_HDD_P2P_CLIENT:
1710 return WIFI_INTERFACE_P2P_CLIENT;
1711 case WLAN_HDD_P2P_GO:
1712 return WIFI_INTERFACE_P2P_GO;
1713 case WLAN_HDD_IBSS:
1714 return WIFI_INTERFACE_IBSS;
1715 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301716 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301717 }
1718}
1719
1720static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1721 tpSirWifiInterfaceInfo pInfo)
1722{
1723 v_U8_t *staMac = NULL;
1724 hdd_station_ctx_t *pHddStaCtx;
1725 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1726 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1727
1728 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1729
1730 vos_mem_copy(pInfo->macAddr,
1731 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1732
1733 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1734 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1735 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1736 {
1737 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1738 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1739 {
1740 pInfo->state = WIFI_DISCONNECTED;
1741 }
1742 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1743 {
1744 hddLog(VOS_TRACE_LEVEL_ERROR,
1745 "%s: Session ID %d, Connection is in progress", __func__,
1746 pAdapter->sessionId);
1747 pInfo->state = WIFI_ASSOCIATING;
1748 }
1749 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1750 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1751 {
1752 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1753 hddLog(VOS_TRACE_LEVEL_ERROR,
1754 "%s: client " MAC_ADDRESS_STR
1755 " is in the middle of WPS/EAPOL exchange.", __func__,
1756 MAC_ADDR_ARRAY(staMac));
1757 pInfo->state = WIFI_AUTHENTICATING;
1758 }
1759 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1760 {
1761 pInfo->state = WIFI_ASSOCIATED;
1762 vos_mem_copy(pInfo->bssid,
1763 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1764 vos_mem_copy(pInfo->ssid,
1765 pHddStaCtx->conn_info.SSID.SSID.ssId,
1766 pHddStaCtx->conn_info.SSID.SSID.length);
1767 //NULL Terminate the string.
1768 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1769 }
1770 }
1771 vos_mem_copy(pInfo->countryStr,
1772 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1773
1774 vos_mem_copy(pInfo->apCountryStr,
1775 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1776
1777 return TRUE;
1778}
1779
1780/*
1781 * hdd_link_layer_process_peer_stats () - This function is called after
1782 * receiving Link Layer Peer statistics from FW.This function converts
1783 * the firmware data to the NL data and sends the same to the kernel/upper
1784 * layers.
1785 */
1786static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1787 v_VOID_t *pData)
1788{
1789 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301790 tpSirWifiPeerStat pWifiPeerStat;
1791 tpSirWifiPeerInfo pWifiPeerInfo;
1792 struct nlattr *peerInfo;
1793 struct sk_buff *vendor_event;
1794 int status, i;
1795
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301796 ENTER();
1797
Sunil Duttc69bccb2014-05-26 21:30:20 +05301798 status = wlan_hdd_validate_context(pHddCtx);
1799 if (0 != status)
1800 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301801 return;
1802 }
1803
1804 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1805
1806 hddLog(VOS_TRACE_LEVEL_INFO,
1807 "LL_STATS_PEER_ALL : numPeers %u",
1808 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301809 /*
1810 * Allocate a size of 4096 for the peer stats comprising
1811 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1812 * sizeof (tSirWifiRateStat).Each field is put with an
1813 * NL attribute.The size of 4096 is considered assuming
1814 * that number of rates shall not exceed beyond 50 with
1815 * the sizeof (tSirWifiRateStat) being 32.
1816 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301817 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1818 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301819 if (!vendor_event)
1820 {
1821 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301822 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301823 __func__);
1824 return;
1825 }
1826 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301827 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1828 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1829 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301830 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1831 pWifiPeerStat->numPeers))
1832 {
1833 hddLog(VOS_TRACE_LEVEL_ERROR,
1834 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1835 kfree_skb(vendor_event);
1836 return;
1837 }
1838
1839 peerInfo = nla_nest_start(vendor_event,
1840 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301841 if(!peerInfo)
1842 {
1843 hddLog(VOS_TRACE_LEVEL_ERROR,
1844 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1845 __func__);
1846 kfree_skb(vendor_event);
1847 return;
1848 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301849
1850 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1851 pWifiPeerStat->peerInfo);
1852
1853 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1854 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301855 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301856 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301857
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301858 if(!peers)
1859 {
1860 hddLog(VOS_TRACE_LEVEL_ERROR,
1861 "%s: peer stats put fail",
1862 __func__);
1863 kfree_skb(vendor_event);
1864 return;
1865 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301866 if (FALSE == put_wifi_peer_info(
1867 pWifiPeerInfo, vendor_event))
1868 {
1869 hddLog(VOS_TRACE_LEVEL_ERROR,
1870 "%s: put_wifi_peer_info put fail", __func__);
1871 kfree_skb(vendor_event);
1872 return;
1873 }
1874
1875 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1876 pWifiPeerStat->peerInfo +
1877 (i * sizeof(tSirWifiPeerInfo)) +
1878 (numRate * sizeof (tSirWifiRateStat)));
1879 nla_nest_end(vendor_event, peers);
1880 }
1881 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301882 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301883 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301884}
1885
1886/*
1887 * hdd_link_layer_process_iface_stats () - This function is called after
1888 * receiving Link Layer Interface statistics from FW.This function converts
1889 * the firmware data to the NL data and sends the same to the kernel/upper
1890 * layers.
1891 */
1892static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1893 v_VOID_t *pData)
1894{
1895 tpSirWifiIfaceStat pWifiIfaceStat;
1896 struct sk_buff *vendor_event;
1897 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1898 int status;
1899
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301900 ENTER();
1901
Sunil Duttc69bccb2014-05-26 21:30:20 +05301902 status = wlan_hdd_validate_context(pHddCtx);
1903 if (0 != status)
1904 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301905 return;
1906 }
1907 /*
1908 * Allocate a size of 4096 for the interface stats comprising
1909 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1910 * assuming that all these fit with in the limit.Please take
1911 * a call on the limit based on the data requirements on
1912 * interface statistics.
1913 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301914 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1915 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301916 if (!vendor_event)
1917 {
1918 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301919 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301920 return;
1921 }
1922
1923 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1924
Dino Mycle3b9536d2014-07-09 22:05:24 +05301925
1926 if (FALSE == hdd_get_interface_info( pAdapter,
1927 &pWifiIfaceStat->info))
1928 {
1929 hddLog(VOS_TRACE_LEVEL_ERROR,
1930 FL("hdd_get_interface_info get fail") );
1931 kfree_skb(vendor_event);
1932 return;
1933 }
1934
1935 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1936 vendor_event))
1937 {
1938 hddLog(VOS_TRACE_LEVEL_ERROR,
1939 FL("put_wifi_iface_stats fail") );
1940 kfree_skb(vendor_event);
1941 return;
1942 }
1943
Sunil Duttc69bccb2014-05-26 21:30:20 +05301944 hddLog(VOS_TRACE_LEVEL_INFO,
1945 "WMI_LINK_STATS_IFACE Data");
1946
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301947 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301948
1949 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301950}
1951
1952/*
1953 * hdd_link_layer_process_radio_stats () - This function is called after
1954 * receiving Link Layer Radio statistics from FW.This function converts
1955 * the firmware data to the NL data and sends the same to the kernel/upper
1956 * layers.
1957 */
1958static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1959 v_VOID_t *pData)
1960{
1961 int status, i;
1962 tpSirWifiRadioStat pWifiRadioStat;
1963 tpSirWifiChannelStats pWifiChannelStats;
1964 struct sk_buff *vendor_event;
1965 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1966 struct nlattr *chList;
1967
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301968 ENTER();
1969
Sunil Duttc69bccb2014-05-26 21:30:20 +05301970 status = wlan_hdd_validate_context(pHddCtx);
1971 if (0 != status)
1972 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301973 return;
1974 }
1975 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1976
1977 hddLog(VOS_TRACE_LEVEL_INFO,
1978 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301979 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05301980 " radio is %d onTime is %u "
1981 " txTime is %u rxTime is %u "
1982 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301983 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301984 " onTimePnoScan is %u onTimeHs20 is %u "
1985 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301986 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301987 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1988 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1989 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301990 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301991 pWifiRadioStat->onTimeRoamScan,
1992 pWifiRadioStat->onTimePnoScan,
1993 pWifiRadioStat->onTimeHs20,
1994 pWifiRadioStat->numChannels);
1995 /*
1996 * Allocate a size of 4096 for the Radio stats comprising
1997 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1998 * (tSirWifiChannelStats).Each channel data is put with an
1999 * NL attribute.The size of 4096 is considered assuming that
2000 * number of channels shall not exceed beyond 60 with the
2001 * sizeof (tSirWifiChannelStats) being 24 bytes.
2002 */
2003
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302004 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2005 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302006 if (!vendor_event)
2007 {
2008 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302009 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302010 return;
2011 }
2012
2013 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302014 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2015 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2016 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302017 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2018 pWifiRadioStat->radio) ||
2019 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302020 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2021 NUM_RADIOS) ||
2022 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302023 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2024 pWifiRadioStat->onTime) ||
2025 nla_put_u32(vendor_event,
2026 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2027 pWifiRadioStat->txTime) ||
2028 nla_put_u32(vendor_event,
2029 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2030 pWifiRadioStat->rxTime) ||
2031 nla_put_u32(vendor_event,
2032 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2033 pWifiRadioStat->onTimeScan) ||
2034 nla_put_u32(vendor_event,
2035 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2036 pWifiRadioStat->onTimeNbd) ||
2037 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302038 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2039 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302040 nla_put_u32(vendor_event,
2041 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2042 pWifiRadioStat->onTimeRoamScan) ||
2043 nla_put_u32(vendor_event,
2044 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2045 pWifiRadioStat->onTimePnoScan) ||
2046 nla_put_u32(vendor_event,
2047 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2048 pWifiRadioStat->onTimeHs20) ||
2049 nla_put_u32(vendor_event,
2050 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2051 pWifiRadioStat->numChannels))
2052 {
2053 hddLog(VOS_TRACE_LEVEL_ERROR,
2054 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2055 kfree_skb(vendor_event);
2056 return ;
2057 }
2058
2059 chList = nla_nest_start(vendor_event,
2060 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302061 if(!chList)
2062 {
2063 hddLog(VOS_TRACE_LEVEL_ERROR,
2064 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2065 __func__);
2066 kfree_skb(vendor_event);
2067 return;
2068 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302069 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2070 {
2071 struct nlattr *chInfo;
2072
2073 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2074 pWifiRadioStat->channels +
2075 (i * sizeof(tSirWifiChannelStats)));
2076
Sunil Duttc69bccb2014-05-26 21:30:20 +05302077 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302078 if(!chInfo)
2079 {
2080 hddLog(VOS_TRACE_LEVEL_ERROR,
2081 "%s: failed to put chInfo",
2082 __func__);
2083 kfree_skb(vendor_event);
2084 return;
2085 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302086
2087 if (nla_put_u32(vendor_event,
2088 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2089 pWifiChannelStats->channel.width) ||
2090 nla_put_u32(vendor_event,
2091 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2092 pWifiChannelStats->channel.centerFreq) ||
2093 nla_put_u32(vendor_event,
2094 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2095 pWifiChannelStats->channel.centerFreq0) ||
2096 nla_put_u32(vendor_event,
2097 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2098 pWifiChannelStats->channel.centerFreq1) ||
2099 nla_put_u32(vendor_event,
2100 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2101 pWifiChannelStats->onTime) ||
2102 nla_put_u32(vendor_event,
2103 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2104 pWifiChannelStats->ccaBusyTime))
2105 {
2106 hddLog(VOS_TRACE_LEVEL_ERROR,
2107 FL("cfg80211_vendor_event_alloc failed") );
2108 kfree_skb(vendor_event);
2109 return ;
2110 }
2111 nla_nest_end(vendor_event, chInfo);
2112 }
2113 nla_nest_end(vendor_event, chList);
2114
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302115 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302116
2117 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302118 return;
2119}
2120
2121/*
2122 * hdd_link_layer_stats_ind_callback () - This function is called after
2123 * receiving Link Layer indications from FW.This callback converts the firmware
2124 * data to the NL data and send the same to the kernel/upper layers.
2125 */
2126static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2127 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302128 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302129{
Dino Mycled3d50022014-07-07 12:58:25 +05302130 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2131 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302132 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302133 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302134 int status;
2135
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302136 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302137
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302138 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302139 if (0 != status)
2140 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302141 return;
2142 }
2143
Dino Mycled3d50022014-07-07 12:58:25 +05302144 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2145 if (NULL == pAdapter)
2146 {
2147 hddLog(VOS_TRACE_LEVEL_ERROR,
2148 FL(" MAC address %pM does not exist with host"),
2149 macAddr);
2150 return;
2151 }
2152
Sunil Duttc69bccb2014-05-26 21:30:20 +05302153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302154 "%s: Interface: %s LLStats indType: %d", __func__,
2155 pAdapter->dev->name, indType);
2156
Sunil Duttc69bccb2014-05-26 21:30:20 +05302157 switch (indType)
2158 {
2159 case SIR_HAL_LL_STATS_RESULTS_RSP:
2160 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302161 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302162 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2163 "respId = %u, moreResultToFollow = %u",
2164 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2165 macAddr, linkLayerStatsResults->respId,
2166 linkLayerStatsResults->moreResultToFollow);
2167
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302168 spin_lock(&hdd_context_lock);
2169 context = &pHddCtx->ll_stats_context;
2170 /* validate response received from target */
2171 if ((context->request_id != linkLayerStatsResults->respId) ||
2172 !(context->request_bitmap & linkLayerStatsResults->paramId))
2173 {
2174 spin_unlock(&hdd_context_lock);
2175 hddLog(LOGE,
2176 FL("Error : Request id %d response id %d request bitmap 0x%x"
2177 "response bitmap 0x%x"),
2178 context->request_id, linkLayerStatsResults->respId,
2179 context->request_bitmap, linkLayerStatsResults->paramId);
2180 return;
2181 }
2182 spin_unlock(&hdd_context_lock);
2183
Sunil Duttc69bccb2014-05-26 21:30:20 +05302184 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2185 {
2186 hdd_link_layer_process_radio_stats(pAdapter,
2187 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302188 spin_lock(&hdd_context_lock);
2189 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2190 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302191 }
2192 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2193 {
2194 hdd_link_layer_process_iface_stats(pAdapter,
2195 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302196 spin_lock(&hdd_context_lock);
2197 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2198 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302199 }
2200 else if ( linkLayerStatsResults->paramId &
2201 WMI_LINK_STATS_ALL_PEER )
2202 {
2203 hdd_link_layer_process_peer_stats(pAdapter,
2204 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302205 spin_lock(&hdd_context_lock);
2206 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2207 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302208 } /* WMI_LINK_STATS_ALL_PEER */
2209 else
2210 {
2211 hddLog(VOS_TRACE_LEVEL_ERROR,
2212 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2213 }
2214
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302215 spin_lock(&hdd_context_lock);
2216 /* complete response event if all requests are completed */
2217 if (0 == context->request_bitmap)
2218 complete(&context->response_event);
2219 spin_unlock(&hdd_context_lock);
2220
Sunil Duttc69bccb2014-05-26 21:30:20 +05302221 break;
2222 }
2223 default:
2224 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2225 break;
2226 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302227
2228 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302229 return;
2230}
2231
2232const struct
2233nla_policy
2234qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2235{
2236 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2237 { .type = NLA_U32 },
2238 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2239 { .type = NLA_U32 },
2240};
2241
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302242static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2243 struct wireless_dev *wdev,
2244 const void *data,
2245 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302246{
2247 int status;
2248 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302249 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302250 struct net_device *dev = wdev->netdev;
2251 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2252 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2253
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302254 ENTER();
2255
Sunil Duttc69bccb2014-05-26 21:30:20 +05302256 status = wlan_hdd_validate_context(pHddCtx);
2257 if (0 != status)
2258 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302259 return -EINVAL;
2260 }
2261
2262 if (NULL == pAdapter)
2263 {
2264 hddLog(VOS_TRACE_LEVEL_ERROR,
2265 FL("HDD adapter is Null"));
2266 return -ENODEV;
2267 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302268 /* check the LLStats Capability */
2269 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2270 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2271 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302272 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302273 FL("Link Layer Statistics not supported by Firmware"));
2274 return -EINVAL;
2275 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302276
2277 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2278 (struct nlattr *)data,
2279 data_len, qca_wlan_vendor_ll_set_policy))
2280 {
2281 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2282 return -EINVAL;
2283 }
2284 if (!tb_vendor
2285 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2286 {
2287 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2288 return -EINVAL;
2289 }
2290 if (!tb_vendor[
2291 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2292 {
2293 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2294 return -EINVAL;
2295 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302296 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302297 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302298
Dino Mycledf0a5d92014-07-04 09:41:55 +05302299 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302300 nla_get_u32(
2301 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2302
Dino Mycledf0a5d92014-07-04 09:41:55 +05302303 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302304 nla_get_u32(
2305 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2306
Dino Mycled3d50022014-07-07 12:58:25 +05302307 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2308 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302309
2310
2311 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302312 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2313 "Statistics Gathering = %d ",
2314 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2315 linkLayerStatsSetReq.mpduSizeThreshold,
2316 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302317
2318 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2319 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302320 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302321 {
2322 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2323 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302324 return -EINVAL;
2325
2326 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302327
Sunil Duttc69bccb2014-05-26 21:30:20 +05302328 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302329 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302330 {
2331 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2332 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302333 return -EINVAL;
2334 }
2335
2336 pAdapter->isLinkLayerStatsSet = 1;
2337
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302338 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302339 return 0;
2340}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302341static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2342 struct wireless_dev *wdev,
2343 const void *data,
2344 int data_len)
2345{
2346 int ret = 0;
2347
2348 vos_ssr_protect(__func__);
2349 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2350 vos_ssr_unprotect(__func__);
2351
2352 return ret;
2353}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302354
2355const struct
2356nla_policy
2357qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2358{
2359 /* Unsigned 32bit value provided by the caller issuing the GET stats
2360 * command. When reporting
2361 * the stats results, the driver uses the same value to indicate
2362 * which GET request the results
2363 * correspond to.
2364 */
2365 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2366
2367 /* Unsigned 32bit value . bit mask to identify what statistics are
2368 requested for retrieval */
2369 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2370};
2371
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302372static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2373 struct wireless_dev *wdev,
2374 const void *data,
2375 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302376{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302377 unsigned long rc;
2378 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302379 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2380 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302381 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302382 struct net_device *dev = wdev->netdev;
2383 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302384 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302385 int status;
2386
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302387 ENTER();
2388
Sunil Duttc69bccb2014-05-26 21:30:20 +05302389 status = wlan_hdd_validate_context(pHddCtx);
2390 if (0 != status)
2391 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302392 return -EINVAL ;
2393 }
2394
2395 if (NULL == pAdapter)
2396 {
2397 hddLog(VOS_TRACE_LEVEL_FATAL,
2398 "%s: HDD adapter is Null", __func__);
2399 return -ENODEV;
2400 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302401
2402 if (pHddStaCtx == NULL)
2403 {
2404 hddLog(VOS_TRACE_LEVEL_FATAL,
2405 "%s: HddStaCtx is Null", __func__);
2406 return -ENODEV;
2407 }
2408
Dino Mycledf0a5d92014-07-04 09:41:55 +05302409 /* check the LLStats Capability */
2410 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2411 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2412 {
2413 hddLog(VOS_TRACE_LEVEL_ERROR,
2414 FL("Link Layer Statistics not supported by Firmware"));
2415 return -EINVAL;
2416 }
2417
Sunil Duttc69bccb2014-05-26 21:30:20 +05302418
2419 if (!pAdapter->isLinkLayerStatsSet)
2420 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302421 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302422 "%s: isLinkLayerStatsSet : %d",
2423 __func__, pAdapter->isLinkLayerStatsSet);
2424 return -EINVAL;
2425 }
2426
Mukul Sharma10313ba2015-07-29 19:14:39 +05302427 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2428 {
2429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2430 "%s: Roaming in progress, so unable to proceed this request", __func__);
2431 return -EBUSY;
2432 }
2433
Sunil Duttc69bccb2014-05-26 21:30:20 +05302434 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2435 (struct nlattr *)data,
2436 data_len, qca_wlan_vendor_ll_get_policy))
2437 {
2438 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2439 return -EINVAL;
2440 }
2441
2442 if (!tb_vendor
2443 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2444 {
2445 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2446 return -EINVAL;
2447 }
2448
2449 if (!tb_vendor
2450 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2451 {
2452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2453 return -EINVAL;
2454 }
2455
Sunil Duttc69bccb2014-05-26 21:30:20 +05302456
Dino Mycledf0a5d92014-07-04 09:41:55 +05302457 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302458 nla_get_u32( tb_vendor[
2459 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302460 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302461 nla_get_u32( tb_vendor[
2462 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2463
Dino Mycled3d50022014-07-07 12:58:25 +05302464 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2465 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302466
2467 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302468 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2469 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302470 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302471
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302472 spin_lock(&hdd_context_lock);
2473 context = &pHddCtx->ll_stats_context;
2474 context->request_id = linkLayerStatsGetReq.reqId;
2475 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
2476 INIT_COMPLETION(context->response_event);
2477 spin_unlock(&hdd_context_lock);
2478
Sunil Duttc69bccb2014-05-26 21:30:20 +05302479 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302480 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302481 {
2482 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2483 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302484 return -EINVAL;
2485 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302486
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302487 rc = wait_for_completion_timeout(&context->response_event,
2488 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
2489 if (!rc)
2490 {
2491 hddLog(LOGE,
2492 FL("Target response timed out request id %d request bitmap 0x%x"),
2493 context->request_id, context->request_bitmap);
2494 return -ETIMEDOUT;
2495 }
2496
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302497 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302498 return 0;
2499}
2500
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302501static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2502 struct wireless_dev *wdev,
2503 const void *data,
2504 int data_len)
2505{
2506 int ret = 0;
2507
2508 vos_ssr_protect(__func__);
2509 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2510 vos_ssr_unprotect(__func__);
2511
2512 return ret;
2513}
2514
Sunil Duttc69bccb2014-05-26 21:30:20 +05302515const struct
2516nla_policy
2517qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2518{
2519 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2520 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2521 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2522 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2523};
2524
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302525static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2526 struct wireless_dev *wdev,
2527 const void *data,
2528 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302529{
2530 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2531 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302532 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302533 struct net_device *dev = wdev->netdev;
2534 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2535 u32 statsClearReqMask;
2536 u8 stopReq;
2537 int status;
2538
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302539 ENTER();
2540
Sunil Duttc69bccb2014-05-26 21:30:20 +05302541 status = wlan_hdd_validate_context(pHddCtx);
2542 if (0 != status)
2543 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302544 return -EINVAL;
2545 }
2546
2547 if (NULL == pAdapter)
2548 {
2549 hddLog(VOS_TRACE_LEVEL_FATAL,
2550 "%s: HDD adapter is Null", __func__);
2551 return -ENODEV;
2552 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302553 /* check the LLStats Capability */
2554 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2555 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2556 {
2557 hddLog(VOS_TRACE_LEVEL_ERROR,
2558 FL("Enable LLStats Capability"));
2559 return -EINVAL;
2560 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302561
2562 if (!pAdapter->isLinkLayerStatsSet)
2563 {
2564 hddLog(VOS_TRACE_LEVEL_FATAL,
2565 "%s: isLinkLayerStatsSet : %d",
2566 __func__, pAdapter->isLinkLayerStatsSet);
2567 return -EINVAL;
2568 }
2569
2570 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2571 (struct nlattr *)data,
2572 data_len, qca_wlan_vendor_ll_clr_policy))
2573 {
2574 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2575 return -EINVAL;
2576 }
2577
2578 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2579
2580 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2581 {
2582 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2583 return -EINVAL;
2584
2585 }
2586
Sunil Duttc69bccb2014-05-26 21:30:20 +05302587
Dino Mycledf0a5d92014-07-04 09:41:55 +05302588 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302589 nla_get_u32(
2590 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2591
Dino Mycledf0a5d92014-07-04 09:41:55 +05302592 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302593 nla_get_u8(
2594 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2595
2596 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302597 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302598
Dino Mycled3d50022014-07-07 12:58:25 +05302599 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2600 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302601
2602 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302603 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2604 "statsClearReqMask = 0x%X, stopReq = %d",
2605 linkLayerStatsClearReq.reqId,
2606 linkLayerStatsClearReq.macAddr,
2607 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302608 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302609
2610 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302611 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302612 {
2613 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302614 hdd_station_ctx_t *pHddStaCtx;
2615
2616 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2617 if (VOS_STATUS_SUCCESS !=
2618 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2619 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2620 {
2621 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2622 "WLANTL_ClearInterfaceStats Failed", __func__);
2623 return -EINVAL;
2624 }
2625 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2626 (statsClearReqMask & WIFI_STATS_IFACE)) {
2627 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2628 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2629 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2630 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2631 }
2632
Sunil Duttc69bccb2014-05-26 21:30:20 +05302633 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2634 2 * sizeof(u32) +
2635 NLMSG_HDRLEN);
2636
2637 if (temp_skbuff != NULL)
2638 {
2639
2640 if (nla_put_u32(temp_skbuff,
2641 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2642 statsClearReqMask) ||
2643 nla_put_u32(temp_skbuff,
2644 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2645 stopReq))
2646 {
2647 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2648 kfree_skb(temp_skbuff);
2649 return -EINVAL;
2650 }
2651 /* If the ask is to stop the stats collection as part of clear
2652 * (stopReq = 1) , ensure that no further requests of get
2653 * go to the firmware by having isLinkLayerStatsSet set to 0.
2654 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302655 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302656 * case the firmware is just asked to clear the statistics.
2657 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302658 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302659 pAdapter->isLinkLayerStatsSet = 0;
2660 return cfg80211_vendor_cmd_reply(temp_skbuff);
2661 }
2662 return -ENOMEM;
2663 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302664
2665 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302666 return -EINVAL;
2667}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302668static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2669 struct wireless_dev *wdev,
2670 const void *data,
2671 int data_len)
2672{
2673 int ret = 0;
2674
2675 vos_ssr_protect(__func__);
2676 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2677 vos_ssr_unprotect(__func__);
2678
2679 return ret;
2680
2681
2682}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302683#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2684
Dino Mycle6fb96c12014-06-10 11:52:40 +05302685#ifdef WLAN_FEATURE_EXTSCAN
2686static const struct nla_policy
2687wlan_hdd_extscan_config_policy
2688 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2689{
2690 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2691 { .type = NLA_U32 },
2692 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2693 { .type = NLA_U32 },
2694 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2695 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2696 { .type = NLA_U32 },
2697 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2698 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2699
2700 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2701 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2702 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2703 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2704 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302705 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2706 { .type = NLA_U32 },
2707 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2708 { .type = NLA_U32 },
2709 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2710 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302711 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2712 { .type = NLA_U32 },
2713 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2714 { .type = NLA_U32 },
2715 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2716 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302717 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2718 { .type = NLA_U8 },
2719 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302720 { .type = NLA_U8 },
2721 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2722 { .type = NLA_U8 },
2723 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2724 { .type = NLA_U8 },
2725
2726 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2727 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05302728 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
2729 .type = NLA_UNSPEC,
2730 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05302731 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2732 { .type = NLA_S32 },
2733 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2734 { .type = NLA_S32 },
2735 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2736 { .type = NLA_U32 },
2737 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2738 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302739 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2740 { .type = NLA_U32 },
2741 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2742 { .type = NLA_BINARY,
2743 .len = IEEE80211_MAX_SSID_LEN + 1 },
2744 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302745 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302746 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2747 { .type = NLA_U32 },
2748 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2749 { .type = NLA_U8 },
2750 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2751 { .type = NLA_S32 },
2752 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2753 { .type = NLA_S32 },
2754 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2755 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302756};
2757
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302758/**
2759 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2760 * @ctx: hdd global context
2761 * @data: capabilities data
2762 *
2763 * Return: none
2764 */
2765static void
2766wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302767{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302768 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302769 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302770 tSirEXTScanCapabilitiesEvent *data =
2771 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302772
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302773 ENTER();
2774
2775 if (wlan_hdd_validate_context(pHddCtx))
2776 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302777 return;
2778 }
2779
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302780 if (!pMsg)
2781 {
2782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2783 return;
2784 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302785
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302786 vos_spin_lock_acquire(&hdd_context_lock);
2787
2788 context = &pHddCtx->ext_scan_context;
2789 /* validate response received from target*/
2790 if (context->request_id != data->requestId)
2791 {
2792 vos_spin_lock_release(&hdd_context_lock);
2793 hddLog(LOGE,
2794 FL("Target response id did not match: request_id %d resposne_id %d"),
2795 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302796 return;
2797 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302798 else
2799 {
2800 context->capability_response = *data;
2801 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302802 }
2803
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302804 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302805
Dino Mycle6fb96c12014-06-10 11:52:40 +05302806 return;
2807}
2808
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302809/*
2810 * define short names for the global vendor params
2811 * used by wlan_hdd_send_ext_scan_capability()
2812 */
2813#define PARAM_REQUEST_ID \
2814 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2815#define PARAM_STATUS \
2816 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2817#define MAX_SCAN_CACHE_SIZE \
2818 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2819#define MAX_SCAN_BUCKETS \
2820 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2821#define MAX_AP_CACHE_PER_SCAN \
2822 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2823#define MAX_RSSI_SAMPLE_SIZE \
2824 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2825#define MAX_SCAN_RPT_THRHOLD \
2826 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2827#define MAX_HOTLIST_BSSIDS \
2828 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2829#define MAX_BSSID_HISTORY_ENTRIES \
2830 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2831#define MAX_HOTLIST_SSIDS \
2832 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302833#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2834 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302835
2836static int wlan_hdd_send_ext_scan_capability(void *ctx)
2837{
2838 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2839 struct sk_buff *skb = NULL;
2840 int ret;
2841 tSirEXTScanCapabilitiesEvent *data;
2842 tANI_U32 nl_buf_len;
2843
2844 ret = wlan_hdd_validate_context(pHddCtx);
2845 if (0 != ret)
2846 {
2847 return ret;
2848 }
2849
2850 data = &(pHddCtx->ext_scan_context.capability_response);
2851
2852 nl_buf_len = NLMSG_HDRLEN;
2853 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2854 (sizeof(data->status) + NLA_HDRLEN) +
2855 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2856 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2857 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2858 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2859 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2860 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2861 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2862 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2863
2864 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2865
2866 if (!skb)
2867 {
2868 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2869 return -ENOMEM;
2870 }
2871
2872 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2873 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2874 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2875 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2876 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2877 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2878 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2879 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2880
2881 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2882 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2883 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2884 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2885 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2886 data->maxApPerScan) ||
2887 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2888 data->maxRssiSampleSize) ||
2889 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2890 data->maxScanReportingThreshold) ||
2891 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2892 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2893 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302894 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2895 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302896 {
2897 hddLog(LOGE, FL("nla put fail"));
2898 goto nla_put_failure;
2899 }
2900
2901 cfg80211_vendor_cmd_reply(skb);
2902 return 0;
2903
2904nla_put_failure:
2905 kfree_skb(skb);
2906 return -EINVAL;;
2907}
2908
2909/*
2910 * done with short names for the global vendor params
2911 * used by wlan_hdd_send_ext_scan_capability()
2912 */
2913#undef PARAM_REQUEST_ID
2914#undef PARAM_STATUS
2915#undef MAX_SCAN_CACHE_SIZE
2916#undef MAX_SCAN_BUCKETS
2917#undef MAX_AP_CACHE_PER_SCAN
2918#undef MAX_RSSI_SAMPLE_SIZE
2919#undef MAX_SCAN_RPT_THRHOLD
2920#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302921#undef MAX_BSSID_HISTORY_ENTRIES
2922#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302923
2924static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2925{
2926 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2927 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302928 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302929 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302930
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302931 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302932
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302933 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302934 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302935
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302936 if (!pMsg)
2937 {
2938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302939 return;
2940 }
2941
Dino Mycle6fb96c12014-06-10 11:52:40 +05302942 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2943 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2944
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302945 context = &pHddCtx->ext_scan_context;
2946 spin_lock(&hdd_context_lock);
2947 if (context->request_id == pData->requestId) {
2948 context->response_status = pData->status ? -EINVAL : 0;
2949 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302950 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302951 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302952
2953 /*
2954 * Store the Request ID for comparing with the requestID obtained
2955 * in other requests.HDD shall return a failure is the extscan_stop
2956 * request is issued with a different requestId as that of the
2957 * extscan_start request. Also, This requestId shall be used while
2958 * indicating the full scan results to the upper layers.
2959 * The requestId is stored with the assumption that the firmware
2960 * shall return the ext scan start request's requestId in ext scan
2961 * start response.
2962 */
2963 if (pData->status == 0)
2964 pMac->sme.extScanStartReqId = pData->requestId;
2965
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302966 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302967 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302968}
2969
2970
2971static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2972{
2973 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2974 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302975 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302976
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302977 ENTER();
2978
2979 if (wlan_hdd_validate_context(pHddCtx)){
2980 return;
2981 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302982
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302983 if (!pMsg)
2984 {
2985 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302986 return;
2987 }
2988
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302989 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2990 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302991
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302992 context = &pHddCtx->ext_scan_context;
2993 spin_lock(&hdd_context_lock);
2994 if (context->request_id == pData->requestId) {
2995 context->response_status = pData->status ? -EINVAL : 0;
2996 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302997 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302998 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302999
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303000 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303001 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303002}
3003
Dino Mycle6fb96c12014-06-10 11:52:40 +05303004static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3005 void *pMsg)
3006{
3007 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303008 tpSirEXTScanSetBssidHotListRspParams pData =
3009 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303010 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303011
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303012 ENTER();
3013
3014 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303015 return;
3016 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303017
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303018 if (!pMsg)
3019 {
3020 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3021 return;
3022 }
3023
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303024 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3025 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303026
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303027 context = &pHddCtx->ext_scan_context;
3028 spin_lock(&hdd_context_lock);
3029 if (context->request_id == pData->requestId) {
3030 context->response_status = pData->status ? -EINVAL : 0;
3031 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303032 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303033 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303034
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303035 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303036 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303037}
3038
3039static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3040 void *pMsg)
3041{
3042 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303043 tpSirEXTScanResetBssidHotlistRspParams pData =
3044 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303045 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303046
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303047 ENTER();
3048
3049 if (wlan_hdd_validate_context(pHddCtx)) {
3050 return;
3051 }
3052 if (!pMsg)
3053 {
3054 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303055 return;
3056 }
3057
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303058 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3059 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303060
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303061 context = &pHddCtx->ext_scan_context;
3062 spin_lock(&hdd_context_lock);
3063 if (context->request_id == pData->requestId) {
3064 context->response_status = pData->status ? -EINVAL : 0;
3065 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303066 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303067 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303068
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303069 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303070 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303071}
3072
Dino Mycle6fb96c12014-06-10 11:52:40 +05303073static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3074 void *pMsg)
3075{
3076 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3077 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303078 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303079 tANI_S32 totalResults;
3080 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303081 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3082 struct hdd_ext_scan_context *context;
3083 bool ignore_cached_results = false;
3084 tExtscanCachedScanResult *result;
3085 struct nlattr *nla_results;
3086 tANI_U16 ieLength= 0;
3087 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303088
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303089 ENTER();
3090
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303091 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303092 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303093
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303094 if (!pMsg)
3095 {
3096 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3097 return;
3098 }
3099
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303100 spin_lock(&hdd_context_lock);
3101 context = &pHddCtx->ext_scan_context;
3102 ignore_cached_results = context->ignore_cached_results;
3103 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303104
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303105 if (ignore_cached_results) {
3106 hddLog(LOGE,
3107 FL("Ignore the cached results received after timeout"));
3108 return;
3109 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303110
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303111 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3112 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303113
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303114 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303115
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303116 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3117 scan_id_index++) {
3118 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303119
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303120 totalResults = result->num_results;
3121 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3122 result->scan_id, result->flags, totalResults);
3123 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303124
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303125 do{
3126 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3127 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3128 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303129
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303130 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3131 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3132
3133 if (!skb) {
3134 hddLog(VOS_TRACE_LEVEL_ERROR,
3135 FL("cfg80211_vendor_event_alloc failed"));
3136 return;
3137 }
3138
3139 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3140
3141 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3142 pData->requestId) ||
3143 nla_put_u32(skb,
3144 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3145 resultsPerEvent)) {
3146 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3147 goto fail;
3148 }
3149 if (nla_put_u8(skb,
3150 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3151 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303152 {
3153 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3154 goto fail;
3155 }
3156
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303157 if (nla_put_u32(skb,
3158 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3159 result->scan_id)) {
3160 hddLog(LOGE, FL("put fail"));
3161 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303162 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303163
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303164 nla_results = nla_nest_start(skb,
3165 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3166 if (!nla_results)
3167 goto fail;
3168
3169 if (resultsPerEvent) {
3170 struct nlattr *aps;
3171 struct nlattr *nla_result;
3172
3173 nla_result = nla_nest_start(skb, scan_id_index);
3174 if(!nla_result)
3175 goto fail;
3176
3177 if (nla_put_u32(skb,
3178 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3179 result->scan_id) ||
3180 nla_put_u32(skb,
3181 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3182 result->flags) ||
3183 nla_put_u32(skb,
3184 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3185 totalResults)) {
3186 hddLog(LOGE, FL("put fail"));
3187 goto fail;
3188 }
3189
3190 aps = nla_nest_start(skb,
3191 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3192 if (!aps)
3193 {
3194 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3195 goto fail;
3196 }
3197
3198 head_ptr = (tpSirWifiScanResult) &(result->ap);
3199
3200 for (j = 0; j < resultsPerEvent; j++, i++) {
3201 struct nlattr *ap;
3202 pSirWifiScanResult = head_ptr + i;
3203
3204 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303205 * Firmware returns timestamp from extscan_start till
3206 * BSSID was cached (in micro seconds). Add this with
3207 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303208 * to derive the time since boot when the
3209 * BSSID was cached.
3210 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303211 pSirWifiScanResult->ts +=
3212 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303213 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3214 "Ssid (%s)"
3215 "Bssid: %pM "
3216 "Channel (%u)"
3217 "Rssi (%d)"
3218 "RTT (%u)"
3219 "RTT_SD (%u)"
3220 "Beacon Period %u"
3221 "Capability 0x%x "
3222 "Ie length %d",
3223 i,
3224 pSirWifiScanResult->ts,
3225 pSirWifiScanResult->ssid,
3226 pSirWifiScanResult->bssid,
3227 pSirWifiScanResult->channel,
3228 pSirWifiScanResult->rssi,
3229 pSirWifiScanResult->rtt,
3230 pSirWifiScanResult->rtt_sd,
3231 pSirWifiScanResult->beaconPeriod,
3232 pSirWifiScanResult->capability,
3233 ieLength);
3234
3235 ap = nla_nest_start(skb, j + 1);
3236 if (!ap)
3237 {
3238 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3239 goto fail;
3240 }
3241
3242 if (nla_put_u64(skb,
3243 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3244 pSirWifiScanResult->ts) )
3245 {
3246 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3247 goto fail;
3248 }
3249 if (nla_put(skb,
3250 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3251 sizeof(pSirWifiScanResult->ssid),
3252 pSirWifiScanResult->ssid) )
3253 {
3254 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3255 goto fail;
3256 }
3257 if (nla_put(skb,
3258 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3259 sizeof(pSirWifiScanResult->bssid),
3260 pSirWifiScanResult->bssid) )
3261 {
3262 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3263 goto fail;
3264 }
3265 if (nla_put_u32(skb,
3266 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3267 pSirWifiScanResult->channel) )
3268 {
3269 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3270 goto fail;
3271 }
3272 if (nla_put_s32(skb,
3273 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3274 pSirWifiScanResult->rssi) )
3275 {
3276 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3277 goto fail;
3278 }
3279 if (nla_put_u32(skb,
3280 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3281 pSirWifiScanResult->rtt) )
3282 {
3283 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3284 goto fail;
3285 }
3286 if (nla_put_u32(skb,
3287 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3288 pSirWifiScanResult->rtt_sd))
3289 {
3290 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3291 goto fail;
3292 }
3293 if (nla_put_u32(skb,
3294 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3295 pSirWifiScanResult->beaconPeriod))
3296 {
3297 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3298 goto fail;
3299 }
3300 if (nla_put_u32(skb,
3301 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3302 pSirWifiScanResult->capability))
3303 {
3304 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3305 goto fail;
3306 }
3307 if (nla_put_u32(skb,
3308 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3309 ieLength))
3310 {
3311 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3312 goto fail;
3313 }
3314
3315 if (ieLength)
3316 if (nla_put(skb,
3317 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3318 ieLength, ie)) {
3319 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3320 goto fail;
3321 }
3322
3323 nla_nest_end(skb, ap);
3324 }
3325 nla_nest_end(skb, aps);
3326 nla_nest_end(skb, nla_result);
3327 }
3328
3329 nla_nest_end(skb, nla_results);
3330
3331 cfg80211_vendor_cmd_reply(skb);
3332
3333 } while (totalResults > 0);
3334 }
3335
3336 if (!pData->moreData) {
3337 spin_lock(&hdd_context_lock);
3338 context->response_status = 0;
3339 complete(&context->response_event);
3340 spin_unlock(&hdd_context_lock);
3341 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303342
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303343 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303344 return;
3345fail:
3346 kfree_skb(skb);
3347 return;
3348}
3349
3350static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3351 void *pMsg)
3352{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303353 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303354 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3355 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303356 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303357
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303358 ENTER();
3359
3360 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303361 hddLog(LOGE,
3362 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303363 return;
3364 }
3365 if (!pMsg)
3366 {
3367 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303368 return;
3369 }
3370
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303371 if (pData->bss_found)
3372 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3373 else
3374 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3375
Dino Mycle6fb96c12014-06-10 11:52:40 +05303376 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303377#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3378 NULL,
3379#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303380 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303381 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303382
3383 if (!skb) {
3384 hddLog(VOS_TRACE_LEVEL_ERROR,
3385 FL("cfg80211_vendor_event_alloc failed"));
3386 return;
3387 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303388
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303389 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3390 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3391 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3392 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3393
3394 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303395 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3396 "Ssid (%s) "
3397 "Bssid (" MAC_ADDRESS_STR ") "
3398 "Channel (%u) "
3399 "Rssi (%d) "
3400 "RTT (%u) "
3401 "RTT_SD (%u) ",
3402 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303403 pData->bssHotlist[i].ts,
3404 pData->bssHotlist[i].ssid,
3405 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3406 pData->bssHotlist[i].channel,
3407 pData->bssHotlist[i].rssi,
3408 pData->bssHotlist[i].rtt,
3409 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303410 }
3411
3412 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3413 pData->requestId) ||
3414 nla_put_u32(skb,
3415 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303416 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303417 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3418 goto fail;
3419 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303420 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303421 struct nlattr *aps;
3422
3423 aps = nla_nest_start(skb,
3424 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3425 if (!aps)
3426 goto fail;
3427
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303428 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303429 struct nlattr *ap;
3430
3431 ap = nla_nest_start(skb, i + 1);
3432 if (!ap)
3433 goto fail;
3434
3435 if (nla_put_u64(skb,
3436 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303437 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303438 nla_put(skb,
3439 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303440 sizeof(pData->bssHotlist[i].ssid),
3441 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303442 nla_put(skb,
3443 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303444 sizeof(pData->bssHotlist[i].bssid),
3445 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303446 nla_put_u32(skb,
3447 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303448 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303449 nla_put_s32(skb,
3450 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303451 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303452 nla_put_u32(skb,
3453 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303454 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303455 nla_put_u32(skb,
3456 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303457 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303458 goto fail;
3459
3460 nla_nest_end(skb, ap);
3461 }
3462 nla_nest_end(skb, aps);
3463
3464 if (nla_put_u8(skb,
3465 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3466 pData->moreData))
3467 goto fail;
3468 }
3469
3470 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303471 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303472 return;
3473
3474fail:
3475 kfree_skb(skb);
3476 return;
3477
3478}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303479
3480static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3481 void *pMsg)
3482{
3483 struct sk_buff *skb;
3484 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3485 tpSirWifiFullScanResultEvent pData =
3486 (tpSirWifiFullScanResultEvent) (pMsg);
3487
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303488 ENTER();
3489
3490 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303491 hddLog(LOGE,
3492 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303493 return;
3494 }
3495 if (!pMsg)
3496 {
3497 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303498 return;
3499 }
3500
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303501 /*
3502 * If the full scan result including IE data exceeds NL 4K size
3503 * limitation, drop that beacon/probe rsp frame.
3504 */
3505 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3506 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3507 return;
3508 }
3509
Dino Mycle6fb96c12014-06-10 11:52:40 +05303510 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303511#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3512 NULL,
3513#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303514 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3515 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3516 GFP_KERNEL);
3517
3518 if (!skb) {
3519 hddLog(VOS_TRACE_LEVEL_ERROR,
3520 FL("cfg80211_vendor_event_alloc failed"));
3521 return;
3522 }
3523
Dino Mycle6fb96c12014-06-10 11:52:40 +05303524 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3525 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3526 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3527 "Ssid (%s)"
3528 "Bssid (" MAC_ADDRESS_STR ")"
3529 "Channel (%u)"
3530 "Rssi (%d)"
3531 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303532 "RTT_SD (%u)"
3533 "Bcn Period %d"
3534 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303535 pData->ap.ts,
3536 pData->ap.ssid,
3537 MAC_ADDR_ARRAY(pData->ap.bssid),
3538 pData->ap.channel,
3539 pData->ap.rssi,
3540 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303541 pData->ap.rtt_sd,
3542 pData->ap.beaconPeriod,
3543 pData->ap.capability);
3544
Dino Mycle6fb96c12014-06-10 11:52:40 +05303545 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3546 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3547 pData->requestId) ||
3548 nla_put_u64(skb,
3549 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3550 pData->ap.ts) ||
3551 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3552 sizeof(pData->ap.ssid),
3553 pData->ap.ssid) ||
3554 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3555 WNI_CFG_BSSID_LEN,
3556 pData->ap.bssid) ||
3557 nla_put_u32(skb,
3558 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3559 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303560 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303561 pData->ap.rssi) ||
3562 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3563 pData->ap.rtt) ||
3564 nla_put_u32(skb,
3565 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3566 pData->ap.rtt_sd) ||
3567 nla_put_u16(skb,
3568 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3569 pData->ap.beaconPeriod) ||
3570 nla_put_u16(skb,
3571 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3572 pData->ap.capability) ||
3573 nla_put_u32(skb,
3574 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303575 pData->ieLength) ||
3576 nla_put_u8(skb,
3577 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3578 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303579 {
3580 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3581 goto nla_put_failure;
3582 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303583
3584 if (pData->ieLength) {
3585 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3586 pData->ieLength,
3587 pData->ie))
3588 {
3589 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3590 goto nla_put_failure;
3591 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303592 }
3593
3594 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303595 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303596 return;
3597
3598nla_put_failure:
3599 kfree_skb(skb);
3600 return;
3601}
3602
3603static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3604 void *pMsg)
3605{
3606 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3607 struct sk_buff *skb = NULL;
3608 tpSirEXTScanResultsAvailableIndParams pData =
3609 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3610
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303611 ENTER();
3612
3613 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303614 hddLog(LOGE,
3615 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303616 return;
3617 }
3618 if (!pMsg)
3619 {
3620 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303621 return;
3622 }
3623
3624 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303625#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3626 NULL,
3627#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303628 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3629 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3630 GFP_KERNEL);
3631
3632 if (!skb) {
3633 hddLog(VOS_TRACE_LEVEL_ERROR,
3634 FL("cfg80211_vendor_event_alloc failed"));
3635 return;
3636 }
3637
Dino Mycle6fb96c12014-06-10 11:52:40 +05303638 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3639 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3640 pData->numResultsAvailable);
3641 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3642 pData->requestId) ||
3643 nla_put_u32(skb,
3644 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3645 pData->numResultsAvailable)) {
3646 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3647 goto nla_put_failure;
3648 }
3649
3650 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303651 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303652 return;
3653
3654nla_put_failure:
3655 kfree_skb(skb);
3656 return;
3657}
3658
3659static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3660{
3661 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3662 struct sk_buff *skb = NULL;
3663 tpSirEXTScanProgressIndParams pData =
3664 (tpSirEXTScanProgressIndParams) pMsg;
3665
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303666 ENTER();
3667
3668 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303669 hddLog(LOGE,
3670 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303671 return;
3672 }
3673 if (!pMsg)
3674 {
3675 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303676 return;
3677 }
3678
3679 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303680#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3681 NULL,
3682#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303683 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3684 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3685 GFP_KERNEL);
3686
3687 if (!skb) {
3688 hddLog(VOS_TRACE_LEVEL_ERROR,
3689 FL("cfg80211_vendor_event_alloc failed"));
3690 return;
3691 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303692 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303693 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3694 pData->extScanEventType);
3695 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3696 pData->status);
3697
3698 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3699 pData->extScanEventType) ||
3700 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303701 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3702 pData->requestId) ||
3703 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303704 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3705 pData->status)) {
3706 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3707 goto nla_put_failure;
3708 }
3709
3710 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303711 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303712 return;
3713
3714nla_put_failure:
3715 kfree_skb(skb);
3716 return;
3717}
3718
3719void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3720 void *pMsg)
3721{
3722 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3723
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303724 ENTER();
3725
Dino Mycle6fb96c12014-06-10 11:52:40 +05303726 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303727 return;
3728 }
3729
3730 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3731
3732
3733 switch(evType) {
3734 case SIR_HAL_EXTSCAN_START_RSP:
3735 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3736 break;
3737
3738 case SIR_HAL_EXTSCAN_STOP_RSP:
3739 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3740 break;
3741 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3742 /* There is no need to send this response to upper layer
3743 Just log the message */
3744 hddLog(VOS_TRACE_LEVEL_INFO,
3745 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3746 break;
3747 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3748 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3749 break;
3750
3751 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3752 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3753 break;
3754
Dino Mycle6fb96c12014-06-10 11:52:40 +05303755 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303756 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303757 break;
3758 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3759 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3760 break;
3761 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3762 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3763 break;
3764 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3765 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3766 break;
3767 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3768 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3769 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303770 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3771 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3772 break;
3773 default:
3774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3775 break;
3776 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303777 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303778}
3779
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303780static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3781 struct wireless_dev *wdev,
3782 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303783{
Dino Myclee8843b32014-07-04 14:21:45 +05303784 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303785 struct net_device *dev = wdev->netdev;
3786 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3787 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3788 struct nlattr
3789 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3790 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303791 struct hdd_ext_scan_context *context;
3792 unsigned long rc;
3793 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303794
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303795 ENTER();
3796
Dino Mycle6fb96c12014-06-10 11:52:40 +05303797 status = wlan_hdd_validate_context(pHddCtx);
3798 if (0 != status)
3799 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303800 return -EINVAL;
3801 }
Dino Myclee8843b32014-07-04 14:21:45 +05303802 /* check the EXTScan Capability */
3803 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303804 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3805 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303806 {
3807 hddLog(VOS_TRACE_LEVEL_ERROR,
3808 FL("EXTScan not enabled/supported by Firmware"));
3809 return -EINVAL;
3810 }
3811
Dino Mycle6fb96c12014-06-10 11:52:40 +05303812 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3813 data, dataLen,
3814 wlan_hdd_extscan_config_policy)) {
3815 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3816 return -EINVAL;
3817 }
3818
3819 /* Parse and fetch request Id */
3820 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3821 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3822 return -EINVAL;
3823 }
3824
Dino Myclee8843b32014-07-04 14:21:45 +05303825 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303826 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303827 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303828
Dino Myclee8843b32014-07-04 14:21:45 +05303829 reqMsg.sessionId = pAdapter->sessionId;
3830 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303831
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303832 vos_spin_lock_acquire(&hdd_context_lock);
3833 context = &pHddCtx->ext_scan_context;
3834 context->request_id = reqMsg.requestId;
3835 INIT_COMPLETION(context->response_event);
3836 vos_spin_lock_release(&hdd_context_lock);
3837
Dino Myclee8843b32014-07-04 14:21:45 +05303838 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303839 if (!HAL_STATUS_SUCCESS(status)) {
3840 hddLog(VOS_TRACE_LEVEL_ERROR,
3841 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303842 return -EINVAL;
3843 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303844
3845 rc = wait_for_completion_timeout(&context->response_event,
3846 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3847 if (!rc) {
3848 hddLog(LOGE, FL("Target response timed out"));
3849 return -ETIMEDOUT;
3850 }
3851
3852 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3853 if (ret)
3854 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3855
3856 return ret;
3857
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303858 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303859 return 0;
3860}
3861
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303862static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3863 struct wireless_dev *wdev,
3864 const void *data, int dataLen)
3865{
3866 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303867
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303868 vos_ssr_protect(__func__);
3869 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3870 vos_ssr_unprotect(__func__);
3871
3872 return ret;
3873}
3874
3875static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3876 struct wireless_dev *wdev,
3877 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303878{
Dino Myclee8843b32014-07-04 14:21:45 +05303879 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303880 struct net_device *dev = wdev->netdev;
3881 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3882 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3883 struct nlattr
3884 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3885 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303886 struct hdd_ext_scan_context *context;
3887 unsigned long rc;
3888 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303889
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303890 ENTER();
3891
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303892 if (VOS_FTM_MODE == hdd_get_conparam()) {
3893 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3894 return -EINVAL;
3895 }
3896
Dino Mycle6fb96c12014-06-10 11:52:40 +05303897 status = wlan_hdd_validate_context(pHddCtx);
3898 if (0 != status)
3899 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303900 return -EINVAL;
3901 }
Dino Myclee8843b32014-07-04 14:21:45 +05303902 /* check the EXTScan Capability */
3903 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303904 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3905 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303906 {
3907 hddLog(VOS_TRACE_LEVEL_ERROR,
3908 FL("EXTScan not enabled/supported by Firmware"));
3909 return -EINVAL;
3910 }
3911
Dino Mycle6fb96c12014-06-10 11:52:40 +05303912 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3913 data, dataLen,
3914 wlan_hdd_extscan_config_policy)) {
3915 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3916 return -EINVAL;
3917 }
3918 /* Parse and fetch request Id */
3919 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3920 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3921 return -EINVAL;
3922 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303923
Dino Myclee8843b32014-07-04 14:21:45 +05303924 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303925 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3926
Dino Myclee8843b32014-07-04 14:21:45 +05303927 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303928
Dino Myclee8843b32014-07-04 14:21:45 +05303929 reqMsg.sessionId = pAdapter->sessionId;
3930 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303931
3932 /* Parse and fetch flush parameter */
3933 if (!tb
3934 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3935 {
3936 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3937 goto failed;
3938 }
Dino Myclee8843b32014-07-04 14:21:45 +05303939 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303940 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3941
Dino Myclee8843b32014-07-04 14:21:45 +05303942 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303943
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303944 spin_lock(&hdd_context_lock);
3945 context = &pHddCtx->ext_scan_context;
3946 context->request_id = reqMsg.requestId;
3947 context->ignore_cached_results = false;
3948 INIT_COMPLETION(context->response_event);
3949 spin_unlock(&hdd_context_lock);
3950
Dino Myclee8843b32014-07-04 14:21:45 +05303951 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303952 if (!HAL_STATUS_SUCCESS(status)) {
3953 hddLog(VOS_TRACE_LEVEL_ERROR,
3954 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303955 return -EINVAL;
3956 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303957
3958 rc = wait_for_completion_timeout(&context->response_event,
3959 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3960 if (!rc) {
3961 hddLog(LOGE, FL("Target response timed out"));
3962 retval = -ETIMEDOUT;
3963 spin_lock(&hdd_context_lock);
3964 context->ignore_cached_results = true;
3965 spin_unlock(&hdd_context_lock);
3966 } else {
3967 spin_lock(&hdd_context_lock);
3968 retval = context->response_status;
3969 spin_unlock(&hdd_context_lock);
3970 }
3971
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303972 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303973 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303974
3975failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303976 return -EINVAL;
3977}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303978static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3979 struct wireless_dev *wdev,
3980 const void *data, int dataLen)
3981{
3982 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303983
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303984 vos_ssr_protect(__func__);
3985 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3986 vos_ssr_unprotect(__func__);
3987
3988 return ret;
3989}
3990
3991static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303992 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303993 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303994{
3995 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3996 struct net_device *dev = wdev->netdev;
3997 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3998 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3999 struct nlattr
4000 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4001 struct nlattr
4002 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4003 struct nlattr *apTh;
4004 eHalStatus status;
4005 tANI_U8 i = 0;
4006 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304007 struct hdd_ext_scan_context *context;
4008 tANI_U32 request_id;
4009 unsigned long rc;
4010 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304011
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304012 ENTER();
4013
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304014 if (VOS_FTM_MODE == hdd_get_conparam()) {
4015 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4016 return -EINVAL;
4017 }
4018
Dino Mycle6fb96c12014-06-10 11:52:40 +05304019 status = wlan_hdd_validate_context(pHddCtx);
4020 if (0 != status)
4021 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304022 return -EINVAL;
4023 }
Dino Myclee8843b32014-07-04 14:21:45 +05304024 /* check the EXTScan Capability */
4025 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304026 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4027 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304028 {
4029 hddLog(VOS_TRACE_LEVEL_ERROR,
4030 FL("EXTScan not enabled/supported by Firmware"));
4031 return -EINVAL;
4032 }
4033
Dino Mycle6fb96c12014-06-10 11:52:40 +05304034 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4035 data, dataLen,
4036 wlan_hdd_extscan_config_policy)) {
4037 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4038 return -EINVAL;
4039 }
4040
4041 /* Parse and fetch request Id */
4042 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4043 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4044 return -EINVAL;
4045 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304046 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4047 vos_mem_malloc(sizeof(*pReqMsg));
4048 if (!pReqMsg) {
4049 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4050 return -ENOMEM;
4051 }
4052
Dino Myclee8843b32014-07-04 14:21:45 +05304053
Dino Mycle6fb96c12014-06-10 11:52:40 +05304054 pReqMsg->requestId = nla_get_u32(
4055 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4056 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4057
4058 /* Parse and fetch number of APs */
4059 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4061 goto fail;
4062 }
4063
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304064 /* Parse and fetch lost ap sample size */
4065 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4066 hddLog(LOGE, FL("attr lost ap sample size failed"));
4067 goto fail;
4068 }
4069
4070 pReqMsg->lostBssidSampleSize = nla_get_u32(
4071 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4072 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4073
Dino Mycle6fb96c12014-06-10 11:52:40 +05304074 pReqMsg->sessionId = pAdapter->sessionId;
4075 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4076
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304077 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304078 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304079 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4080 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4081 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4082 goto fail;
4083 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304084 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304085
4086 nla_for_each_nested(apTh,
4087 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304088 if (i == pReqMsg->numBssid) {
4089 hddLog(LOGW, FL("Ignoring excess AP"));
4090 break;
4091 }
4092
Dino Mycle6fb96c12014-06-10 11:52:40 +05304093 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4094 nla_data(apTh), nla_len(apTh),
4095 NULL)) {
4096 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4097 goto fail;
4098 }
4099
4100 /* Parse and fetch MAC address */
4101 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4102 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4103 goto fail;
4104 }
4105 memcpy(pReqMsg->ap[i].bssid, nla_data(
4106 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4107 sizeof(tSirMacAddr));
4108 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4109
4110 /* Parse and fetch low RSSI */
4111 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4112 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4113 goto fail;
4114 }
4115 pReqMsg->ap[i].low = nla_get_s32(
4116 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4117 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4118
4119 /* Parse and fetch high RSSI */
4120 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4121 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4122 goto fail;
4123 }
4124 pReqMsg->ap[i].high = nla_get_s32(
4125 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4126 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4127 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304128 i++;
4129 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304130
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304131 if (i < pReqMsg->numBssid) {
4132 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4133 i, pReqMsg->numBssid);
4134 pReqMsg->numBssid = i;
4135 }
4136
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304137 context = &pHddCtx->ext_scan_context;
4138 spin_lock(&hdd_context_lock);
4139 INIT_COMPLETION(context->response_event);
4140 context->request_id = request_id = pReqMsg->requestId;
4141 spin_unlock(&hdd_context_lock);
4142
Dino Mycle6fb96c12014-06-10 11:52:40 +05304143 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4144 if (!HAL_STATUS_SUCCESS(status)) {
4145 hddLog(VOS_TRACE_LEVEL_ERROR,
4146 FL("sme_SetBssHotlist failed(err=%d)"), status);
4147 vos_mem_free(pReqMsg);
4148 return -EINVAL;
4149 }
4150
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304151 /* request was sent -- wait for the response */
4152 rc = wait_for_completion_timeout(&context->response_event,
4153 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4154
4155 if (!rc) {
4156 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4157 retval = -ETIMEDOUT;
4158 } else {
4159 spin_lock(&hdd_context_lock);
4160 if (context->request_id == request_id)
4161 retval = context->response_status;
4162 else
4163 retval = -EINVAL;
4164 spin_unlock(&hdd_context_lock);
4165 }
4166
Dino Myclee8843b32014-07-04 14:21:45 +05304167 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304168 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304169 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304170
4171fail:
4172 vos_mem_free(pReqMsg);
4173 return -EINVAL;
4174}
4175
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304176static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4177 struct wireless_dev *wdev,
4178 const void *data, int dataLen)
4179{
4180 int ret = 0;
4181
4182 vos_ssr_protect(__func__);
4183 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4184 dataLen);
4185 vos_ssr_unprotect(__func__);
4186
4187 return ret;
4188}
4189
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304190static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304191 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304192 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304193{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304194 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4195 struct net_device *dev = wdev->netdev;
4196 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4197 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4198 uint8_t num_channels = 0;
4199 uint8_t num_chan_new = 0;
4200 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304201 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304202 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304203 tWifiBand wifiBand;
4204 eHalStatus status;
4205 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304206 tANI_U8 i,j,k;
4207 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304208
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304209 ENTER();
4210
Dino Mycle6fb96c12014-06-10 11:52:40 +05304211 status = wlan_hdd_validate_context(pHddCtx);
4212 if (0 != status)
4213 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304214 return -EINVAL;
4215 }
Dino Myclee8843b32014-07-04 14:21:45 +05304216
Dino Mycle6fb96c12014-06-10 11:52:40 +05304217 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4218 data, dataLen,
4219 wlan_hdd_extscan_config_policy)) {
4220 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4221 return -EINVAL;
4222 }
4223
4224 /* Parse and fetch request Id */
4225 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4226 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4227 return -EINVAL;
4228 }
4229 requestId = nla_get_u32(
4230 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4231 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4232
4233 /* Parse and fetch wifi band */
4234 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4235 {
4236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4237 return -EINVAL;
4238 }
4239 wifiBand = nla_get_u32(
4240 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4241 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4242
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304243 /* Parse and fetch max channels */
4244 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4245 {
4246 hddLog(LOGE, FL("attr max channels failed"));
4247 return -EINVAL;
4248 }
4249 maxChannels = nla_get_u32(
4250 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4251 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4252
Dino Mycle6fb96c12014-06-10 11:52:40 +05304253 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304254 wifiBand, chan_list,
4255 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304256 if (eHAL_STATUS_SUCCESS != status) {
4257 hddLog(VOS_TRACE_LEVEL_ERROR,
4258 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4259 return -EINVAL;
4260 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304261
Agrawal Ashish16abf782016-08-18 22:42:59 +05304262 num_channels = VOS_MIN(num_channels, maxChannels);
4263 num_chan_new = num_channels;
4264 /* remove the indoor only channels if iface is SAP */
4265 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4266 {
4267 num_chan_new = 0;
4268 for (i = 0; i < num_channels; i++)
4269 for (j = 0; j < IEEE80211_NUM_BANDS; j++) {
4270 if (wiphy->bands[j] == NULL)
4271 continue;
4272 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4273 if ((chan_list[i] ==
4274 wiphy->bands[j]->channels[k].center_freq) &&
4275 (!(wiphy->bands[j]->channels[k].flags &
4276 IEEE80211_CHAN_INDOOR_ONLY))) {
4277 chan_list[num_chan_new] = chan_list[i];
4278 num_chan_new++;
4279 }
4280 }
4281 }
4282 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304283
Agrawal Ashish16abf782016-08-18 22:42:59 +05304284 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4285 for (i = 0; i < num_chan_new; i++)
4286 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4287 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304288
4289 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304290 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304291 NLMSG_HDRLEN);
4292
4293 if (!replySkb) {
4294 hddLog(VOS_TRACE_LEVEL_ERROR,
4295 FL("valid channels: buffer alloc fail"));
4296 return -EINVAL;
4297 }
4298 if (nla_put_u32(replySkb,
4299 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304300 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304301 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304302 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304303
4304 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4305 kfree_skb(replySkb);
4306 return -EINVAL;
4307 }
4308
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304309 ret = cfg80211_vendor_cmd_reply(replySkb);
4310
4311 EXIT();
4312 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304313}
4314
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304315static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4316 struct wireless_dev *wdev,
4317 const void *data, int dataLen)
4318{
4319 int ret = 0;
4320
4321 vos_ssr_protect(__func__);
4322 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4323 dataLen);
4324 vos_ssr_unprotect(__func__);
4325
4326 return ret;
4327}
4328
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304329static int hdd_extscan_start_fill_bucket_channel_spec(
4330 hdd_context_t *pHddCtx,
4331 tpSirEXTScanStartReqParams pReqMsg,
4332 struct nlattr **tb)
4333{
4334 struct nlattr *bucket[
4335 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4336 struct nlattr *channel[
4337 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4338 struct nlattr *buckets;
4339 struct nlattr *channels;
4340 int rem1, rem2;
4341 eHalStatus status;
4342 tANI_U8 bktIndex, j, numChannels;
4343 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4344 tANI_U32 passive_max_chn_time, active_max_chn_time;
4345
4346 bktIndex = 0;
4347
4348 nla_for_each_nested(buckets,
4349 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4350 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304351 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4352 nla_data(buckets), nla_len(buckets),
4353 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304354 hddLog(LOGE, FL("nla_parse failed"));
4355 return -EINVAL;
4356 }
4357
4358 /* Parse and fetch bucket spec */
4359 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4360 hddLog(LOGE, FL("attr bucket index failed"));
4361 return -EINVAL;
4362 }
4363 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4364 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4365 hddLog(LOG1, FL("Bucket spec Index %d"),
4366 pReqMsg->buckets[bktIndex].bucket);
4367
4368 /* Parse and fetch wifi band */
4369 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4370 hddLog(LOGE, FL("attr wifi band failed"));
4371 return -EINVAL;
4372 }
4373 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4374 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4375 hddLog(LOG1, FL("Wifi band %d"),
4376 pReqMsg->buckets[bktIndex].band);
4377
4378 /* Parse and fetch period */
4379 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4380 hddLog(LOGE, FL("attr period failed"));
4381 return -EINVAL;
4382 }
4383 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4384 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4385 hddLog(LOG1, FL("period %d"),
4386 pReqMsg->buckets[bktIndex].period);
4387
4388 /* Parse and fetch report events */
4389 if (!bucket[
4390 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4391 hddLog(LOGE, FL("attr report events failed"));
4392 return -EINVAL;
4393 }
4394 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4395 bucket[
4396 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4397 hddLog(LOG1, FL("report events %d"),
4398 pReqMsg->buckets[bktIndex].reportEvents);
4399
4400 /* Parse and fetch max period */
4401 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4402 hddLog(LOGE, FL("attr max period failed"));
4403 return -EINVAL;
4404 }
4405 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4406 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4407 hddLog(LOG1, FL("max period %u"),
4408 pReqMsg->buckets[bktIndex].max_period);
4409
4410 /* Parse and fetch exponent */
4411 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4412 hddLog(LOGE, FL("attr exponent failed"));
4413 return -EINVAL;
4414 }
4415 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4416 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4417 hddLog(LOG1, FL("exponent %u"),
4418 pReqMsg->buckets[bktIndex].exponent);
4419
4420 /* Parse and fetch step count */
4421 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4422 hddLog(LOGE, FL("attr step count failed"));
4423 return -EINVAL;
4424 }
4425 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4426 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4427 hddLog(LOG1, FL("Step count %u"),
4428 pReqMsg->buckets[bktIndex].step_count);
4429
4430 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4431 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4432
4433 /* Framework shall pass the channel list if the input WiFi band is
4434 * WIFI_BAND_UNSPECIFIED.
4435 * If the input WiFi band is specified (any value other than
4436 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4437 */
4438 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4439 numChannels = 0;
4440 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4441 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4442 pReqMsg->buckets[bktIndex].band,
4443 chanList, &numChannels);
4444 if (!HAL_STATUS_SUCCESS(status)) {
4445 hddLog(LOGE,
4446 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4447 status);
4448 return -EINVAL;
4449 }
4450
4451 pReqMsg->buckets[bktIndex].numChannels =
4452 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4453 hddLog(LOG1, FL("Num channels %d"),
4454 pReqMsg->buckets[bktIndex].numChannels);
4455
4456 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4457 j++) {
4458 pReqMsg->buckets[bktIndex].channels[j].channel =
4459 chanList[j];
4460 pReqMsg->buckets[bktIndex].channels[j].
4461 chnlClass = 0;
4462 if (CSR_IS_CHANNEL_DFS(
4463 vos_freq_to_chan(chanList[j]))) {
4464 pReqMsg->buckets[bktIndex].channels[j].
4465 passive = 1;
4466 pReqMsg->buckets[bktIndex].channels[j].
4467 dwellTimeMs = passive_max_chn_time;
4468 } else {
4469 pReqMsg->buckets[bktIndex].channels[j].
4470 passive = 0;
4471 pReqMsg->buckets[bktIndex].channels[j].
4472 dwellTimeMs = active_max_chn_time;
4473 }
4474
4475 hddLog(LOG1,
4476 "Channel %u Passive %u Dwell time %u ms",
4477 pReqMsg->buckets[bktIndex].channels[j].channel,
4478 pReqMsg->buckets[bktIndex].channels[j].passive,
4479 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4480 }
4481
4482 bktIndex++;
4483 continue;
4484 }
4485
4486 /* Parse and fetch number of channels */
4487 if (!bucket[
4488 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4489 hddLog(LOGE, FL("attr num channels failed"));
4490 return -EINVAL;
4491 }
4492
4493 pReqMsg->buckets[bktIndex].numChannels =
4494 nla_get_u32(bucket[
4495 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4496 hddLog(LOG1, FL("num channels %d"),
4497 pReqMsg->buckets[bktIndex].numChannels);
4498
4499 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4500 hddLog(LOGE, FL("attr channel spec failed"));
4501 return -EINVAL;
4502 }
4503
4504 j = 0;
4505 nla_for_each_nested(channels,
4506 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4507 if (nla_parse(channel,
4508 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4509 nla_data(channels), nla_len(channels),
4510 wlan_hdd_extscan_config_policy)) {
4511 hddLog(LOGE, FL("nla_parse failed"));
4512 return -EINVAL;
4513 }
4514
4515 /* Parse and fetch channel */
4516 if (!channel[
4517 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4518 hddLog(LOGE, FL("attr channel failed"));
4519 return -EINVAL;
4520 }
4521 pReqMsg->buckets[bktIndex].channels[j].channel =
4522 nla_get_u32(channel[
4523 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4524 hddLog(LOG1, FL("channel %u"),
4525 pReqMsg->buckets[bktIndex].channels[j].channel);
4526
4527 /* Parse and fetch dwell time */
4528 if (!channel[
4529 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4530 hddLog(LOGE, FL("attr dwelltime failed"));
4531 return -EINVAL;
4532 }
4533 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4534 nla_get_u32(channel[
4535 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4536
4537 hddLog(LOG1, FL("Dwell time (%u ms)"),
4538 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4539
4540
4541 /* Parse and fetch channel spec passive */
4542 if (!channel[
4543 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4544 hddLog(LOGE,
4545 FL("attr channel spec passive failed"));
4546 return -EINVAL;
4547 }
4548 pReqMsg->buckets[bktIndex].channels[j].passive =
4549 nla_get_u8(channel[
4550 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4551 hddLog(LOG1, FL("Chnl spec passive %u"),
4552 pReqMsg->buckets[bktIndex].channels[j].passive);
4553
4554 j++;
4555 }
4556
4557 bktIndex++;
4558 }
4559
4560 return 0;
4561}
4562
4563
4564/*
4565 * define short names for the global vendor params
4566 * used by wlan_hdd_cfg80211_extscan_start()
4567 */
4568#define PARAM_MAX \
4569QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4570#define PARAM_REQUEST_ID \
4571QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4572#define PARAM_BASE_PERIOD \
4573QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4574#define PARAM_MAX_AP_PER_SCAN \
4575QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4576#define PARAM_RPT_THRHLD_PERCENT \
4577QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4578#define PARAM_RPT_THRHLD_NUM_SCANS \
4579QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4580#define PARAM_NUM_BUCKETS \
4581QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4582
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304583static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304584 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304585 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304586{
Dino Myclee8843b32014-07-04 14:21:45 +05304587 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304588 struct net_device *dev = wdev->netdev;
4589 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4590 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4591 struct nlattr *tb[PARAM_MAX + 1];
4592 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304593 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304594 tANI_U32 request_id;
4595 struct hdd_ext_scan_context *context;
4596 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304597
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304598 ENTER();
4599
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304600 if (VOS_FTM_MODE == hdd_get_conparam()) {
4601 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4602 return -EINVAL;
4603 }
4604
Dino Mycle6fb96c12014-06-10 11:52:40 +05304605 status = wlan_hdd_validate_context(pHddCtx);
4606 if (0 != status)
4607 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304608 return -EINVAL;
4609 }
Dino Myclee8843b32014-07-04 14:21:45 +05304610 /* check the EXTScan Capability */
4611 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304612 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4613 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304614 {
4615 hddLog(VOS_TRACE_LEVEL_ERROR,
4616 FL("EXTScan not enabled/supported by Firmware"));
4617 return -EINVAL;
4618 }
4619
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304620 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304621 data, dataLen,
4622 wlan_hdd_extscan_config_policy)) {
4623 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4624 return -EINVAL;
4625 }
4626
4627 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304628 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304629 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4630 return -EINVAL;
4631 }
4632
Dino Myclee8843b32014-07-04 14:21:45 +05304633 pReqMsg = (tpSirEXTScanStartReqParams)
4634 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304635 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304636 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4637 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304638 }
4639
4640 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304641 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304642 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4643
4644 pReqMsg->sessionId = pAdapter->sessionId;
4645 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4646
4647 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304648 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304649 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4650 goto fail;
4651 }
4652 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304653 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304654 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4655 pReqMsg->basePeriod);
4656
4657 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304658 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4660 goto fail;
4661 }
4662 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304663 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304664 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4665 pReqMsg->maxAPperScan);
4666
4667 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304668 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304669 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4670 goto fail;
4671 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304672 pReqMsg->reportThresholdPercent = nla_get_u8(
4673 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304674 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304675 pReqMsg->reportThresholdPercent);
4676
4677 /* Parse and fetch report threshold num scans */
4678 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4679 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4680 goto fail;
4681 }
4682 pReqMsg->reportThresholdNumScans = nla_get_u8(
4683 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4684 hddLog(LOG1, FL("Report Threshold num scans %d"),
4685 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304686
4687 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304688 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304689 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4690 goto fail;
4691 }
4692 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304693 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304694 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4695 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4696 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4697 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4698 }
4699 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4700 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304701
Dino Mycle6fb96c12014-06-10 11:52:40 +05304702 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4703 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4704 goto fail;
4705 }
4706
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304707 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304708
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304709 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4710 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304711
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304712 context = &pHddCtx->ext_scan_context;
4713 spin_lock(&hdd_context_lock);
4714 INIT_COMPLETION(context->response_event);
4715 context->request_id = request_id = pReqMsg->requestId;
4716 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304717
Dino Mycle6fb96c12014-06-10 11:52:40 +05304718 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4719 if (!HAL_STATUS_SUCCESS(status)) {
4720 hddLog(VOS_TRACE_LEVEL_ERROR,
4721 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304722 goto fail;
4723 }
4724
Srinivas Dasari91727c12016-03-23 17:59:06 +05304725 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
4726
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304727 /* request was sent -- wait for the response */
4728 rc = wait_for_completion_timeout(&context->response_event,
4729 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4730
4731 if (!rc) {
4732 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4733 retval = -ETIMEDOUT;
4734 } else {
4735 spin_lock(&hdd_context_lock);
4736 if (context->request_id == request_id)
4737 retval = context->response_status;
4738 else
4739 retval = -EINVAL;
4740 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304741 }
4742
Dino Myclee8843b32014-07-04 14:21:45 +05304743 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304744 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304745 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304746
4747fail:
4748 vos_mem_free(pReqMsg);
4749 return -EINVAL;
4750}
4751
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304752/*
4753 * done with short names for the global vendor params
4754 * used by wlan_hdd_cfg80211_extscan_start()
4755 */
4756#undef PARAM_MAX
4757#undef PARAM_REQUEST_ID
4758#undef PARAM_BASE_PERIOD
4759#undef PARAMS_MAX_AP_PER_SCAN
4760#undef PARAMS_RPT_THRHLD_PERCENT
4761#undef PARAMS_RPT_THRHLD_NUM_SCANS
4762#undef PARAMS_NUM_BUCKETS
4763
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304764static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4765 struct wireless_dev *wdev,
4766 const void *data, int dataLen)
4767{
4768 int ret = 0;
4769
4770 vos_ssr_protect(__func__);
4771 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4772 vos_ssr_unprotect(__func__);
4773
4774 return ret;
4775}
4776
4777static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304778 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304779 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304780{
Dino Myclee8843b32014-07-04 14:21:45 +05304781 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304782 struct net_device *dev = wdev->netdev;
4783 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4784 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4785 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4786 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304787 int retval;
4788 unsigned long rc;
4789 struct hdd_ext_scan_context *context;
4790 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304791
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304792 ENTER();
4793
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304794 if (VOS_FTM_MODE == hdd_get_conparam()) {
4795 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4796 return -EINVAL;
4797 }
4798
Dino Mycle6fb96c12014-06-10 11:52:40 +05304799 status = wlan_hdd_validate_context(pHddCtx);
4800 if (0 != status)
4801 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304802 return -EINVAL;
4803 }
Dino Myclee8843b32014-07-04 14:21:45 +05304804 /* check the EXTScan Capability */
4805 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304806 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4807 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304808 {
4809 hddLog(VOS_TRACE_LEVEL_ERROR,
4810 FL("EXTScan not enabled/supported by Firmware"));
4811 return -EINVAL;
4812 }
4813
Dino Mycle6fb96c12014-06-10 11:52:40 +05304814 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4815 data, dataLen,
4816 wlan_hdd_extscan_config_policy)) {
4817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4818 return -EINVAL;
4819 }
4820
4821 /* Parse and fetch request Id */
4822 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4823 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4824 return -EINVAL;
4825 }
4826
Dino Myclee8843b32014-07-04 14:21:45 +05304827 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304828 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304829 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304830
Dino Myclee8843b32014-07-04 14:21:45 +05304831 reqMsg.sessionId = pAdapter->sessionId;
4832 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304833
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304834 context = &pHddCtx->ext_scan_context;
4835 spin_lock(&hdd_context_lock);
4836 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05304837 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304838 spin_unlock(&hdd_context_lock);
4839
Dino Myclee8843b32014-07-04 14:21:45 +05304840 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304841 if (!HAL_STATUS_SUCCESS(status)) {
4842 hddLog(VOS_TRACE_LEVEL_ERROR,
4843 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304844 return -EINVAL;
4845 }
4846
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304847 /* request was sent -- wait for the response */
4848 rc = wait_for_completion_timeout(&context->response_event,
4849 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4850
4851 if (!rc) {
4852 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4853 retval = -ETIMEDOUT;
4854 } else {
4855 spin_lock(&hdd_context_lock);
4856 if (context->request_id == request_id)
4857 retval = context->response_status;
4858 else
4859 retval = -EINVAL;
4860 spin_unlock(&hdd_context_lock);
4861 }
4862
4863 return retval;
4864
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304865 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304866 return 0;
4867}
4868
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304869static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4870 struct wireless_dev *wdev,
4871 const void *data, int dataLen)
4872{
4873 int ret = 0;
4874
4875 vos_ssr_protect(__func__);
4876 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4877 vos_ssr_unprotect(__func__);
4878
4879 return ret;
4880}
4881
4882static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304883 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304884 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304885{
Dino Myclee8843b32014-07-04 14:21:45 +05304886 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304887 struct net_device *dev = wdev->netdev;
4888 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4889 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4890 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4891 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304892 struct hdd_ext_scan_context *context;
4893 tANI_U32 request_id;
4894 unsigned long rc;
4895 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304896
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304897 ENTER();
4898
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304899 if (VOS_FTM_MODE == hdd_get_conparam()) {
4900 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4901 return -EINVAL;
4902 }
4903
Dino Mycle6fb96c12014-06-10 11:52:40 +05304904 status = wlan_hdd_validate_context(pHddCtx);
4905 if (0 != status)
4906 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304907 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304908 return -EINVAL;
4909 }
Dino Myclee8843b32014-07-04 14:21:45 +05304910 /* check the EXTScan Capability */
4911 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304912 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4913 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304914 {
4915 hddLog(VOS_TRACE_LEVEL_ERROR,
4916 FL("EXTScan not enabled/supported by Firmware"));
4917 return -EINVAL;
4918 }
4919
Dino Mycle6fb96c12014-06-10 11:52:40 +05304920 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4921 data, dataLen,
4922 wlan_hdd_extscan_config_policy)) {
4923 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4924 return -EINVAL;
4925 }
4926
4927 /* Parse and fetch request Id */
4928 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4930 return -EINVAL;
4931 }
4932
Dino Myclee8843b32014-07-04 14:21:45 +05304933 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304934 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304935 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304936
Dino Myclee8843b32014-07-04 14:21:45 +05304937 reqMsg.sessionId = pAdapter->sessionId;
4938 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304939
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304940 context = &pHddCtx->ext_scan_context;
4941 spin_lock(&hdd_context_lock);
4942 INIT_COMPLETION(context->response_event);
4943 context->request_id = request_id = reqMsg.requestId;
4944 spin_unlock(&hdd_context_lock);
4945
Dino Myclee8843b32014-07-04 14:21:45 +05304946 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304947 if (!HAL_STATUS_SUCCESS(status)) {
4948 hddLog(VOS_TRACE_LEVEL_ERROR,
4949 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304950 return -EINVAL;
4951 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304952
4953 /* request was sent -- wait for the response */
4954 rc = wait_for_completion_timeout(&context->response_event,
4955 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4956 if (!rc) {
4957 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4958 retval = -ETIMEDOUT;
4959 } else {
4960 spin_lock(&hdd_context_lock);
4961 if (context->request_id == request_id)
4962 retval = context->response_status;
4963 else
4964 retval = -EINVAL;
4965 spin_unlock(&hdd_context_lock);
4966 }
4967
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304968 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304969 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304970}
4971
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304972static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4973 struct wireless_dev *wdev,
4974 const void *data, int dataLen)
4975{
4976 int ret = 0;
4977
4978 vos_ssr_protect(__func__);
4979 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4980 vos_ssr_unprotect(__func__);
4981
4982 return ret;
4983}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304984#endif /* WLAN_FEATURE_EXTSCAN */
4985
Atul Mittal115287b2014-07-08 13:26:33 +05304986/*EXT TDLS*/
4987static const struct nla_policy
4988wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4989{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05304990 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
4991 .type = NLA_UNSPEC,
4992 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05304993 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4994 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4995 {.type = NLA_S32 },
4996 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4997 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4998
4999};
5000
5001static const struct nla_policy
5002wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5003{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305004 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5005 .type = NLA_UNSPEC,
5006 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305007
5008};
5009
5010static const struct nla_policy
5011wlan_hdd_tdls_config_state_change_policy[
5012 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5013{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305014 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5015 .type = NLA_UNSPEC,
5016 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305017 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5018 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305019 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5020 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5021 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305022
5023};
5024
5025static const struct nla_policy
5026wlan_hdd_tdls_config_get_status_policy[
5027 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5028{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305029 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5030 .type = NLA_UNSPEC,
5031 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305032 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5033 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305034 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5035 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5036 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305037
5038};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305039
5040static const struct nla_policy
5041wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5042{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305043 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5044 .type = NLA_UNSPEC,
5045 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305046};
5047
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305048static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305049 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305050 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305051 int data_len)
5052{
5053
5054 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5055 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5056
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305057 ENTER();
5058
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305059 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305060 return -EINVAL;
5061 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305062 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305063 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305064 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305065 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305066 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305067 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305068 return -ENOTSUPP;
5069 }
5070
5071 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5072 data, data_len, wlan_hdd_mac_config)) {
5073 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5074 return -EINVAL;
5075 }
5076
5077 /* Parse and fetch mac address */
5078 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5079 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5080 return -EINVAL;
5081 }
5082
5083 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5084 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5085 VOS_MAC_ADDR_LAST_3_BYTES);
5086
Siddharth Bhal76972212014-10-15 16:22:51 +05305087 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5088
5089 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305090 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5091 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305092 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5093 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5094 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5095 {
5096 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5097 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5098 VOS_MAC_ADDRESS_LEN);
5099 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305100 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305101
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305102 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5103 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305104
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305105 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305106 return 0;
5107}
5108
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305109static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5110 struct wireless_dev *wdev,
5111 const void *data,
5112 int data_len)
5113{
5114 int ret = 0;
5115
5116 vos_ssr_protect(__func__);
5117 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5118 vos_ssr_unprotect(__func__);
5119
5120 return ret;
5121}
5122
5123static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305124 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305125 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305126 int data_len)
5127{
5128 u8 peer[6] = {0};
5129 struct net_device *dev = wdev->netdev;
5130 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5131 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5132 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5133 eHalStatus ret;
5134 tANI_S32 state;
5135 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305136 tANI_S32 global_operating_class = 0;
5137 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305138 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305139 int retVal;
5140
5141 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305142
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305143 if (!pAdapter) {
5144 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5145 return -EINVAL;
5146 }
5147
Atul Mittal115287b2014-07-08 13:26:33 +05305148 ret = wlan_hdd_validate_context(pHddCtx);
5149 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305150 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305151 return -EINVAL;
5152 }
5153 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305154 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305155 return -ENOTSUPP;
5156 }
5157 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5158 data, data_len,
5159 wlan_hdd_tdls_config_get_status_policy)) {
5160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5161 return -EINVAL;
5162 }
5163
5164 /* Parse and fetch mac address */
5165 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5166 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5167 return -EINVAL;
5168 }
5169
5170 memcpy(peer, nla_data(
5171 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5172 sizeof(peer));
5173 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5174
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305175 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305176
Atul Mittal115287b2014-07-08 13:26:33 +05305177 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305178 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305179 NLMSG_HDRLEN);
5180
5181 if (!skb) {
5182 hddLog(VOS_TRACE_LEVEL_ERROR,
5183 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5184 return -EINVAL;
5185 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305186 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 +05305187 reason,
5188 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305189 global_operating_class,
5190 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305191 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305192 if (nla_put_s32(skb,
5193 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5194 state) ||
5195 nla_put_s32(skb,
5196 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5197 reason) ||
5198 nla_put_s32(skb,
5199 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5200 global_operating_class) ||
5201 nla_put_s32(skb,
5202 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5203 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305204
5205 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5206 goto nla_put_failure;
5207 }
5208
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305209 retVal = cfg80211_vendor_cmd_reply(skb);
5210 EXIT();
5211 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305212
5213nla_put_failure:
5214 kfree_skb(skb);
5215 return -EINVAL;
5216}
5217
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305218static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5219 struct wireless_dev *wdev,
5220 const void *data,
5221 int data_len)
5222{
5223 int ret = 0;
5224
5225 vos_ssr_protect(__func__);
5226 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5227 vos_ssr_unprotect(__func__);
5228
5229 return ret;
5230}
5231
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305232static int wlan_hdd_cfg80211_exttdls_callback(
5233#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5234 const tANI_U8* mac,
5235#else
5236 tANI_U8* mac,
5237#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305238 tANI_S32 state,
5239 tANI_S32 reason,
5240 void *ctx)
5241{
5242 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305243 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305244 tANI_S32 global_operating_class = 0;
5245 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305246 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305247
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305248 ENTER();
5249
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305250 if (!pAdapter) {
5251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5252 return -EINVAL;
5253 }
5254
5255 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305256 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305257 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305258 return -EINVAL;
5259 }
5260
5261 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305262 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305263 return -ENOTSUPP;
5264 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305265 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5266#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5267 NULL,
5268#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305269 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5270 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5271 GFP_KERNEL);
5272
5273 if (!skb) {
5274 hddLog(VOS_TRACE_LEVEL_ERROR,
5275 FL("cfg80211_vendor_event_alloc failed"));
5276 return -EINVAL;
5277 }
5278 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305279 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5280 reason,
5281 state,
5282 global_operating_class,
5283 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305284 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5285 MAC_ADDR_ARRAY(mac));
5286
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305287 if (nla_put(skb,
5288 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5289 VOS_MAC_ADDR_SIZE, mac) ||
5290 nla_put_s32(skb,
5291 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5292 state) ||
5293 nla_put_s32(skb,
5294 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5295 reason) ||
5296 nla_put_s32(skb,
5297 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5298 channel) ||
5299 nla_put_s32(skb,
5300 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5301 global_operating_class)
5302 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305303 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5304 goto nla_put_failure;
5305 }
5306
5307 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305308 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305309 return (0);
5310
5311nla_put_failure:
5312 kfree_skb(skb);
5313 return -EINVAL;
5314}
5315
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305316static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305317 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305318 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305319 int data_len)
5320{
5321 u8 peer[6] = {0};
5322 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305323 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5324 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5325 eHalStatus status;
5326 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305327 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305328 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305329
5330 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305331
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305332 if (!dev) {
5333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5334 return -EINVAL;
5335 }
5336
5337 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5338 if (!pAdapter) {
5339 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5340 return -EINVAL;
5341 }
5342
Atul Mittal115287b2014-07-08 13:26:33 +05305343 status = wlan_hdd_validate_context(pHddCtx);
5344 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305346 return -EINVAL;
5347 }
5348 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305349 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305350 return -ENOTSUPP;
5351 }
5352 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5353 data, data_len,
5354 wlan_hdd_tdls_config_enable_policy)) {
5355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5356 return -EINVAL;
5357 }
5358
5359 /* Parse and fetch mac address */
5360 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5361 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5362 return -EINVAL;
5363 }
5364
5365 memcpy(peer, nla_data(
5366 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5367 sizeof(peer));
5368 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5369
5370 /* Parse and fetch channel */
5371 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5372 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5373 return -EINVAL;
5374 }
5375 pReqMsg.channel = nla_get_s32(
5376 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5377 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5378
5379 /* Parse and fetch global operating class */
5380 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5381 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5382 return -EINVAL;
5383 }
5384 pReqMsg.global_operating_class = nla_get_s32(
5385 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5386 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5387 pReqMsg.global_operating_class);
5388
5389 /* Parse and fetch latency ms */
5390 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5391 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5392 return -EINVAL;
5393 }
5394 pReqMsg.max_latency_ms = nla_get_s32(
5395 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5396 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5397 pReqMsg.max_latency_ms);
5398
5399 /* Parse and fetch required bandwidth kbps */
5400 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5401 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5402 return -EINVAL;
5403 }
5404
5405 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5406 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5407 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5408 pReqMsg.min_bandwidth_kbps);
5409
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305410 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305411 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305412 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305413 wlan_hdd_cfg80211_exttdls_callback);
5414
5415 EXIT();
5416 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305417}
5418
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305419static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5420 struct wireless_dev *wdev,
5421 const void *data,
5422 int data_len)
5423{
5424 int ret = 0;
5425
5426 vos_ssr_protect(__func__);
5427 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5428 vos_ssr_unprotect(__func__);
5429
5430 return ret;
5431}
5432
5433static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305434 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305435 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305436 int data_len)
5437{
5438 u8 peer[6] = {0};
5439 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305440 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5441 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5442 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305443 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305444 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305445
5446 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305447
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305448 if (!dev) {
5449 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5450 return -EINVAL;
5451 }
5452
5453 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5454 if (!pAdapter) {
5455 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5456 return -EINVAL;
5457 }
5458
Atul Mittal115287b2014-07-08 13:26:33 +05305459 status = wlan_hdd_validate_context(pHddCtx);
5460 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305461 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305462 return -EINVAL;
5463 }
5464 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305465 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305466 return -ENOTSUPP;
5467 }
5468 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5469 data, data_len,
5470 wlan_hdd_tdls_config_disable_policy)) {
5471 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5472 return -EINVAL;
5473 }
5474 /* Parse and fetch mac address */
5475 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5476 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5477 return -EINVAL;
5478 }
5479
5480 memcpy(peer, nla_data(
5481 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5482 sizeof(peer));
5483 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5484
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305485 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5486
5487 EXIT();
5488 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305489}
5490
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305491static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5492 struct wireless_dev *wdev,
5493 const void *data,
5494 int data_len)
5495{
5496 int ret = 0;
5497
5498 vos_ssr_protect(__func__);
5499 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5500 vos_ssr_unprotect(__func__);
5501
5502 return ret;
5503}
5504
Dasari Srinivas7875a302014-09-26 17:50:57 +05305505static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305506__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305507 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305508 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305509{
5510 struct net_device *dev = wdev->netdev;
5511 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5512 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5513 struct sk_buff *skb = NULL;
5514 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305515 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305516
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305517 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305518
5519 ret = wlan_hdd_validate_context(pHddCtx);
5520 if (0 != ret)
5521 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305522 return ret;
5523 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305524 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5525 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5526 fset |= WIFI_FEATURE_INFRA;
5527 }
5528
5529 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5530 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5531 fset |= WIFI_FEATURE_INFRA_5G;
5532 }
5533
5534#ifdef WLAN_FEATURE_P2P
5535 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5536 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5537 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5538 fset |= WIFI_FEATURE_P2P;
5539 }
5540#endif
5541
5542 /* Soft-AP is supported currently by default */
5543 fset |= WIFI_FEATURE_SOFT_AP;
5544
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305545 /* HOTSPOT is a supplicant feature, enable it by default */
5546 fset |= WIFI_FEATURE_HOTSPOT;
5547
Dasari Srinivas7875a302014-09-26 17:50:57 +05305548#ifdef WLAN_FEATURE_EXTSCAN
5549 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305550 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5551 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5552 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305553 fset |= WIFI_FEATURE_EXTSCAN;
5554 }
5555#endif
5556
Dasari Srinivas7875a302014-09-26 17:50:57 +05305557 if (sme_IsFeatureSupportedByFW(NAN)) {
5558 hddLog(LOG1, FL("NAN is supported by firmware"));
5559 fset |= WIFI_FEATURE_NAN;
5560 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305561
5562 /* D2D RTT is not supported currently by default */
5563 if (sme_IsFeatureSupportedByFW(RTT)) {
5564 hddLog(LOG1, FL("RTT is supported by firmware"));
5565 fset |= WIFI_FEATURE_D2AP_RTT;
5566 }
5567
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305568 if (sme_IsFeatureSupportedByFW(RTT3)) {
5569 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5570 fset |= WIFI_FEATURE_RTT3;
5571 }
5572
Dasari Srinivas7875a302014-09-26 17:50:57 +05305573#ifdef FEATURE_WLAN_BATCH_SCAN
5574 if (fset & WIFI_FEATURE_EXTSCAN) {
5575 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5576 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5577 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5578 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5579 fset |= WIFI_FEATURE_BATCH_SCAN;
5580 }
5581#endif
5582
5583#ifdef FEATURE_WLAN_SCAN_PNO
5584 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5585 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5586 hddLog(LOG1, FL("PNO is supported by firmware"));
5587 fset |= WIFI_FEATURE_PNO;
5588 }
5589#endif
5590
5591 /* STA+STA is supported currently by default */
5592 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5593
5594#ifdef FEATURE_WLAN_TDLS
5595 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5596 sme_IsFeatureSupportedByFW(TDLS)) {
5597 hddLog(LOG1, FL("TDLS is supported by firmware"));
5598 fset |= WIFI_FEATURE_TDLS;
5599 }
5600
5601 /* TDLS_OFFCHANNEL is not supported currently by default */
5602#endif
5603
5604#ifdef WLAN_AP_STA_CONCURRENCY
5605 /* AP+STA concurrency is supported currently by default */
5606 fset |= WIFI_FEATURE_AP_STA;
5607#endif
5608
Mukul Sharma5add0532015-08-17 15:57:47 +05305609#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5610 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5611 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5612#endif
5613
Dasari Srinivas7875a302014-09-26 17:50:57 +05305614 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5615 NLMSG_HDRLEN);
5616
5617 if (!skb) {
5618 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5619 return -EINVAL;
5620 }
5621 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5622
5623 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5624 hddLog(LOGE, FL("nla put fail"));
5625 goto nla_put_failure;
5626 }
5627
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305628 ret = cfg80211_vendor_cmd_reply(skb);
5629 EXIT();
5630 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305631
5632nla_put_failure:
5633 kfree_skb(skb);
5634 return -EINVAL;
5635}
5636
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305637static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305638wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5639 struct wireless_dev *wdev,
5640 const void *data, int data_len)
5641{
5642 int ret = 0;
5643
5644 vos_ssr_protect(__func__);
5645 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5646 vos_ssr_unprotect(__func__);
5647
5648 return ret;
5649}
5650
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305651
5652static const struct
5653nla_policy
5654qca_wlan_vendor_wifi_logger_get_ring_data_policy
5655[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5656 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5657 = {.type = NLA_U32 },
5658};
5659
5660static int
5661 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5662 struct wireless_dev *wdev,
5663 const void *data,
5664 int data_len)
5665{
5666 int ret;
5667 VOS_STATUS status;
5668 uint32_t ring_id;
5669 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5670 struct nlattr *tb
5671 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5672
5673 ENTER();
5674
5675 ret = wlan_hdd_validate_context(hdd_ctx);
5676 if (0 != ret) {
5677 return ret;
5678 }
5679
5680 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5681 data, data_len,
5682 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5683 hddLog(LOGE, FL("Invalid attribute"));
5684 return -EINVAL;
5685 }
5686
5687 /* Parse and fetch ring id */
5688 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5689 hddLog(LOGE, FL("attr ATTR failed"));
5690 return -EINVAL;
5691 }
5692
5693 ring_id = nla_get_u32(
5694 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5695
5696 hddLog(LOG1, FL("Bug report triggered by framework"));
5697
5698 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5699 WLAN_LOG_INDICATOR_FRAMEWORK,
5700 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305701 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305702 );
5703 if (VOS_STATUS_SUCCESS != status) {
5704 hddLog(LOGE, FL("Failed to trigger bug report"));
5705
5706 return -EINVAL;
5707 }
5708
5709 return 0;
5710
5711
5712}
5713
5714
5715static int
5716 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5717 struct wireless_dev *wdev,
5718 const void *data,
5719 int data_len)
5720{
5721 int ret = 0;
5722
5723 vos_ssr_protect(__func__);
5724 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5725 wdev, data, data_len);
5726 vos_ssr_unprotect(__func__);
5727
5728 return ret;
5729
5730}
5731
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305732#define MAX_CONCURRENT_MATRIX \
5733 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
5734#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
5735 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
5736static const struct nla_policy
5737wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
5738 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
5739};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305740
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305741static int
5742__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305743 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305744 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305745{
5746 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5747 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305748 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305749 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305750 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5751 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305752
5753 ENTER();
5754
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305755 ret = wlan_hdd_validate_context(pHddCtx);
5756 if (0 != ret)
5757 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305758 return ret;
5759 }
5760
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305761 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
5762 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305763 hddLog(LOGE, FL("Invalid ATTR"));
5764 return -EINVAL;
5765 }
5766
5767 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305768 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305769 hddLog(LOGE, FL("Attr max feature set size failed"));
5770 return -EINVAL;
5771 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305772 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305773 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5774
5775 /* Fill feature combination matrix */
5776 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305777 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5778 WIFI_FEATURE_P2P;
5779
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305780 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5781 WIFI_FEATURE_SOFT_AP;
5782
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305783 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5784 WIFI_FEATURE_SOFT_AP;
5785
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305786 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5787 WIFI_FEATURE_SOFT_AP |
5788 WIFI_FEATURE_P2P;
5789
5790 /* Add more feature combinations here */
5791
5792 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5793 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5794 hddLog(LOG1, "Feature set matrix");
5795 for (i = 0; i < feature_sets; i++)
5796 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5797
5798 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5799 sizeof(u32) * feature_sets +
5800 NLMSG_HDRLEN);
5801
5802 if (reply_skb) {
5803 if (nla_put_u32(reply_skb,
5804 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5805 feature_sets) ||
5806 nla_put(reply_skb,
5807 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5808 sizeof(u32) * feature_sets, feature_set_matrix)) {
5809 hddLog(LOGE, FL("nla put fail"));
5810 kfree_skb(reply_skb);
5811 return -EINVAL;
5812 }
5813
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305814 ret = cfg80211_vendor_cmd_reply(reply_skb);
5815 EXIT();
5816 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305817 }
5818 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5819 return -ENOMEM;
5820
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305821}
5822
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305823#undef MAX_CONCURRENT_MATRIX
5824#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
5825
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305826static int
5827wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5828 struct wireless_dev *wdev,
5829 const void *data, int data_len)
5830{
5831 int ret = 0;
5832
5833 vos_ssr_protect(__func__);
5834 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5835 data_len);
5836 vos_ssr_unprotect(__func__);
5837
5838 return ret;
5839}
5840
c_manjeecfd1efb2015-09-25 19:32:34 +05305841
5842static int
5843__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5844 struct wireless_dev *wdev,
5845 const void *data, int data_len)
5846{
5847 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5848 int ret;
5849 ENTER();
5850
5851 ret = wlan_hdd_validate_context(pHddCtx);
5852 if (0 != ret)
5853 {
5854 return ret;
5855 }
5856
5857 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5858 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5859 {
5860 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5861 return -EINVAL;
5862 }
5863 /*call common API for FW mem dump req*/
5864 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5865
Abhishek Singhc783fa72015-12-09 18:07:34 +05305866 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305867 {
5868 /*indicate to userspace the status of fw mem dump */
5869 wlan_indicate_mem_dump_complete(true);
5870 }
5871 else
5872 {
5873 /*else send failure to userspace */
5874 wlan_indicate_mem_dump_complete(false);
5875 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305876 EXIT();
5877 return ret;
5878}
5879
5880/**
5881 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5882 * @wiphy: pointer to wireless wiphy structure.
5883 * @wdev: pointer to wireless_dev structure.
5884 * @data: Pointer to the NL data.
5885 * @data_len:Length of @data
5886 *
5887 * This is called when wlan driver needs to get the firmware memory dump
5888 * via vendor specific command.
5889 *
5890 * Return: 0 on success, error number otherwise.
5891 */
5892
5893static int
5894wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5895 struct wireless_dev *wdev,
5896 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305897{
5898 int ret = 0;
5899 vos_ssr_protect(__func__);
5900 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5901 data_len);
5902 vos_ssr_unprotect(__func__);
5903 return ret;
5904}
c_manjeecfd1efb2015-09-25 19:32:34 +05305905
Sushant Kaushik8e644982015-09-23 12:18:54 +05305906static const struct
5907nla_policy
5908qca_wlan_vendor_wifi_logger_start_policy
5909[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5910 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5911 = {.type = NLA_U32 },
5912 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5913 = {.type = NLA_U32 },
5914 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5915 = {.type = NLA_U32 },
5916};
5917
5918/**
5919 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5920 * or disable the collection of packet statistics from the firmware
5921 * @wiphy: WIPHY structure pointer
5922 * @wdev: Wireless device structure pointer
5923 * @data: Pointer to the data received
5924 * @data_len: Length of the data received
5925 *
5926 * This function is used to enable or disable the collection of packet
5927 * statistics from the firmware
5928 *
5929 * Return: 0 on success and errno on failure
5930 */
5931static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5932 struct wireless_dev *wdev,
5933 const void *data,
5934 int data_len)
5935{
5936 eHalStatus status;
5937 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5938 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5939 tAniWifiStartLog start_log;
5940
5941 status = wlan_hdd_validate_context(hdd_ctx);
5942 if (0 != status) {
5943 return -EINVAL;
5944 }
5945
5946 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5947 data, data_len,
5948 qca_wlan_vendor_wifi_logger_start_policy)) {
5949 hddLog(LOGE, FL("Invalid attribute"));
5950 return -EINVAL;
5951 }
5952
5953 /* Parse and fetch ring id */
5954 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5955 hddLog(LOGE, FL("attr ATTR failed"));
5956 return -EINVAL;
5957 }
5958 start_log.ringId = nla_get_u32(
5959 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5960 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5961
5962 /* Parse and fetch verbose level */
5963 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5964 hddLog(LOGE, FL("attr verbose_level failed"));
5965 return -EINVAL;
5966 }
5967 start_log.verboseLevel = nla_get_u32(
5968 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5969 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5970
5971 /* Parse and fetch flag */
5972 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5973 hddLog(LOGE, FL("attr flag failed"));
5974 return -EINVAL;
5975 }
5976 start_log.flag = nla_get_u32(
5977 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5978 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5979
5980 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305981 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5982 !vos_isPktStatsEnabled()))
5983
Sushant Kaushik8e644982015-09-23 12:18:54 +05305984 {
5985 hddLog(LOGE, FL("per pkt stats not enabled"));
5986 return -EINVAL;
5987 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305988
Sushant Kaushik33200572015-08-05 16:46:20 +05305989 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305990 return 0;
5991}
5992
5993/**
5994 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5995 * or disable the collection of packet statistics from the firmware
5996 * @wiphy: WIPHY structure pointer
5997 * @wdev: Wireless device structure pointer
5998 * @data: Pointer to the data received
5999 * @data_len: Length of the data received
6000 *
6001 * This function is used to enable or disable the collection of packet
6002 * statistics from the firmware
6003 *
6004 * Return: 0 on success and errno on failure
6005 */
6006static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6007 struct wireless_dev *wdev,
6008 const void *data,
6009 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306010{
6011 int ret = 0;
6012
6013 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306014
6015 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6016 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306017 vos_ssr_unprotect(__func__);
6018
6019 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306020}
6021
6022
Agarwal Ashish738843c2014-09-25 12:27:56 +05306023static const struct nla_policy
6024wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6025 +1] =
6026{
6027 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6028};
6029
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306030static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306031 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306032 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306033 int data_len)
6034{
6035 struct net_device *dev = wdev->netdev;
6036 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6037 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6038 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6039 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6040 eHalStatus status;
6041 u32 dfsFlag = 0;
6042
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306043 ENTER();
6044
Agarwal Ashish738843c2014-09-25 12:27:56 +05306045 status = wlan_hdd_validate_context(pHddCtx);
6046 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306047 return -EINVAL;
6048 }
6049 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6050 data, data_len,
6051 wlan_hdd_set_no_dfs_flag_config_policy)) {
6052 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6053 return -EINVAL;
6054 }
6055
6056 /* Parse and fetch required bandwidth kbps */
6057 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6058 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6059 return -EINVAL;
6060 }
6061
6062 dfsFlag = nla_get_u32(
6063 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6064 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6065 dfsFlag);
6066
6067 pHddCtx->disable_dfs_flag = dfsFlag;
6068
6069 sme_disable_dfs_channel(hHal, dfsFlag);
6070 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306071
6072 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306073 return 0;
6074}
Atul Mittal115287b2014-07-08 13:26:33 +05306075
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306076static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6077 struct wireless_dev *wdev,
6078 const void *data,
6079 int data_len)
6080{
6081 int ret = 0;
6082
6083 vos_ssr_protect(__func__);
6084 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6085 vos_ssr_unprotect(__func__);
6086
6087 return ret;
6088
6089}
6090
Mukul Sharma2a271632014-10-13 14:59:01 +05306091const struct
6092nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6093{
6094 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306095 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6096 .type = NLA_UNSPEC,
6097 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306098};
6099
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306100static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306101 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306102{
6103
6104 u8 bssid[6] = {0};
6105 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6106 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6107 eHalStatus status = eHAL_STATUS_SUCCESS;
6108 v_U32_t isFwrRoamEnabled = FALSE;
6109 int ret;
6110
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306111 ENTER();
6112
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306113 ret = wlan_hdd_validate_context(pHddCtx);
6114 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306115 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306116 }
6117
6118 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6119 data, data_len,
6120 qca_wlan_vendor_attr);
6121 if (ret){
6122 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6123 return -EINVAL;
6124 }
6125
6126 /* Parse and fetch Enable flag */
6127 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6128 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6129 return -EINVAL;
6130 }
6131
6132 isFwrRoamEnabled = nla_get_u32(
6133 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6134
6135 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6136
6137 /* Parse and fetch bssid */
6138 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6139 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6140 return -EINVAL;
6141 }
6142
6143 memcpy(bssid, nla_data(
6144 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6145 sizeof(bssid));
6146 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6147
6148 //Update roaming
6149 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306150 if (!HAL_STATUS_SUCCESS(status)) {
6151 hddLog(LOGE,
6152 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6153 return -EINVAL;
6154 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306155 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306156 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306157}
6158
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306159static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6160 struct wireless_dev *wdev, const void *data, int data_len)
6161{
6162 int ret = 0;
6163
6164 vos_ssr_protect(__func__);
6165 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6166 vos_ssr_unprotect(__func__);
6167
6168 return ret;
6169}
6170
Sushant Kaushik847890c2015-09-28 16:05:17 +05306171static const struct
6172nla_policy
6173qca_wlan_vendor_get_wifi_info_policy[
6174 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6175 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6176 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6177};
6178
6179
6180/**
6181 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6182 * @wiphy: pointer to wireless wiphy structure.
6183 * @wdev: pointer to wireless_dev structure.
6184 * @data: Pointer to the data to be passed via vendor interface
6185 * @data_len:Length of the data to be passed
6186 *
6187 * This is called when wlan driver needs to send wifi driver related info
6188 * (driver/fw version) to the user space application upon request.
6189 *
6190 * Return: Return the Success or Failure code.
6191 */
6192static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6193 struct wireless_dev *wdev,
6194 const void *data, int data_len)
6195{
6196 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6197 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6198 tSirVersionString version;
6199 uint32 version_len;
6200 uint8 attr;
6201 int status;
6202 struct sk_buff *reply_skb = NULL;
6203
6204 if (VOS_FTM_MODE == hdd_get_conparam()) {
6205 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6206 return -EINVAL;
6207 }
6208
6209 status = wlan_hdd_validate_context(hdd_ctx);
6210 if (0 != status) {
6211 hddLog(LOGE, FL("HDD context is not valid"));
6212 return -EINVAL;
6213 }
6214
6215 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6216 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6217 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6218 return -EINVAL;
6219 }
6220
6221 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6222 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6223 QWLAN_VERSIONSTR);
6224 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6225 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6226 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6227 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6228 hdd_ctx->fw_Version);
6229 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6230 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6231 } else {
6232 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6233 return -EINVAL;
6234 }
6235
6236 version_len = strlen(version);
6237 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6238 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6239 if (!reply_skb) {
6240 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6241 return -ENOMEM;
6242 }
6243
6244 if (nla_put(reply_skb, attr, version_len, version)) {
6245 hddLog(LOGE, FL("nla put fail"));
6246 kfree_skb(reply_skb);
6247 return -EINVAL;
6248 }
6249
6250 return cfg80211_vendor_cmd_reply(reply_skb);
6251}
6252
6253/**
6254 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6255 * @wiphy: pointer to wireless wiphy structure.
6256 * @wdev: pointer to wireless_dev structure.
6257 * @data: Pointer to the data to be passed via vendor interface
6258 * @data_len:Length of the data to be passed
6259 * @data_len: Length of the data received
6260 *
6261 * This function is used to enable or disable the collection of packet
6262 * statistics from the firmware
6263 *
6264 * Return: 0 on success and errno on failure
6265 */
6266
6267static int
6268wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6269 struct wireless_dev *wdev,
6270 const void *data, int data_len)
6271
6272
6273{
6274 int ret = 0;
6275
6276 vos_ssr_protect(__func__);
6277 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6278 wdev, data, data_len);
6279 vos_ssr_unprotect(__func__);
6280
6281 return ret;
6282}
6283
6284
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306285/*
6286 * define short names for the global vendor params
6287 * used by __wlan_hdd_cfg80211_monitor_rssi()
6288 */
6289#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6290#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6291#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6292#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6293#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6294
6295/**---------------------------------------------------------------------------
6296
6297 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6298 monitor start is completed successfully.
6299
6300 \return - None
6301
6302 --------------------------------------------------------------------------*/
6303void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6304{
6305 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6306
6307 if (NULL == pHddCtx)
6308 {
6309 hddLog(VOS_TRACE_LEVEL_ERROR,
6310 "%s: HDD context is NULL",__func__);
6311 return;
6312 }
6313
6314 if (VOS_STATUS_SUCCESS == status)
6315 {
6316 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6317 }
6318 else
6319 {
6320 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6321 }
6322
6323 return;
6324}
6325
6326/**---------------------------------------------------------------------------
6327
6328 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6329 stop is completed successfully.
6330
6331 \return - None
6332
6333 --------------------------------------------------------------------------*/
6334void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6335{
6336 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6337
6338 if (NULL == pHddCtx)
6339 {
6340 hddLog(VOS_TRACE_LEVEL_ERROR,
6341 "%s: HDD context is NULL",__func__);
6342 return;
6343 }
6344
6345 if (VOS_STATUS_SUCCESS == status)
6346 {
6347 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6348 }
6349 else
6350 {
6351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6352 }
6353
6354 return;
6355}
6356
6357/**
6358 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6359 * @wiphy: Pointer to wireless phy
6360 * @wdev: Pointer to wireless device
6361 * @data: Pointer to data
6362 * @data_len: Data length
6363 *
6364 * Return: 0 on success, negative errno on failure
6365 */
6366
6367static int
6368__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6369 struct wireless_dev *wdev,
6370 const void *data,
6371 int data_len)
6372{
6373 struct net_device *dev = wdev->netdev;
6374 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6375 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6376 hdd_station_ctx_t *pHddStaCtx;
6377 struct nlattr *tb[PARAM_MAX + 1];
6378 tpSirRssiMonitorReq pReq;
6379 eHalStatus status;
6380 int ret;
6381 uint32_t control;
6382 static const struct nla_policy policy[PARAM_MAX + 1] = {
6383 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6384 [PARAM_CONTROL] = { .type = NLA_U32 },
6385 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6386 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6387 };
6388
6389 ENTER();
6390
6391 ret = wlan_hdd_validate_context(hdd_ctx);
6392 if (0 != ret) {
6393 return -EINVAL;
6394 }
6395
6396 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6397 hddLog(LOGE, FL("Not in Connected state!"));
6398 return -ENOTSUPP;
6399 }
6400
6401 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6402 hddLog(LOGE, FL("Invalid ATTR"));
6403 return -EINVAL;
6404 }
6405
6406 if (!tb[PARAM_REQUEST_ID]) {
6407 hddLog(LOGE, FL("attr request id failed"));
6408 return -EINVAL;
6409 }
6410
6411 if (!tb[PARAM_CONTROL]) {
6412 hddLog(LOGE, FL("attr control failed"));
6413 return -EINVAL;
6414 }
6415
6416 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6417
6418 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6419 if(NULL == pReq)
6420 {
6421 hddLog(LOGE,
6422 FL("vos_mem_alloc failed "));
6423 return eHAL_STATUS_FAILED_ALLOC;
6424 }
6425 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6426
6427 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6428 pReq->sessionId = pAdapter->sessionId;
6429 pReq->rssiMonitorCbContext = hdd_ctx;
6430 control = nla_get_u32(tb[PARAM_CONTROL]);
6431 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6432
6433 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6434 pReq->requestId, pReq->sessionId, control);
6435
6436 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6437 if (!tb[PARAM_MIN_RSSI]) {
6438 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306439 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306440 }
6441
6442 if (!tb[PARAM_MAX_RSSI]) {
6443 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306444 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306445 }
6446
6447 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6448 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6449 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6450
6451 if (!(pReq->minRssi < pReq->maxRssi)) {
6452 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6453 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306454 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306455 }
6456 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6457 pReq->minRssi, pReq->maxRssi);
6458 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6459
6460 }
6461 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6462 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6463 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6464 }
6465 else {
6466 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306467 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306468 }
6469
6470 if (!HAL_STATUS_SUCCESS(status)) {
6471 hddLog(LOGE,
6472 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306473 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306474 }
6475
6476 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306477fail:
6478 vos_mem_free(pReq);
6479 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306480}
6481
6482/*
6483 * done with short names for the global vendor params
6484 * used by __wlan_hdd_cfg80211_monitor_rssi()
6485 */
6486#undef PARAM_MAX
6487#undef PARAM_CONTROL
6488#undef PARAM_REQUEST_ID
6489#undef PARAM_MAX_RSSI
6490#undef PARAM_MIN_RSSI
6491
6492/**
6493 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6494 * @wiphy: wiphy structure pointer
6495 * @wdev: Wireless device structure pointer
6496 * @data: Pointer to the data received
6497 * @data_len: Length of @data
6498 *
6499 * Return: 0 on success; errno on failure
6500 */
6501static int
6502wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6503 const void *data, int data_len)
6504{
6505 int ret;
6506
6507 vos_ssr_protect(__func__);
6508 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6509 vos_ssr_unprotect(__func__);
6510
6511 return ret;
6512}
6513
6514/**
6515 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6516 * @hddctx: HDD context
6517 * @data: rssi breached event data
6518 *
6519 * This function reads the rssi breached event %data and fill in the skb with
6520 * NL attributes and send up the NL event.
6521 * This callback execute in atomic context and must not invoke any
6522 * blocking calls.
6523 *
6524 * Return: none
6525 */
6526void hdd_rssi_threshold_breached_cb(void *hddctx,
6527 struct rssi_breach_event *data)
6528{
6529 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6530 int status;
6531 struct sk_buff *skb;
6532
6533 ENTER();
6534 status = wlan_hdd_validate_context(pHddCtx);
6535
6536 if (0 != status) {
6537 return;
6538 }
6539
6540 if (!data) {
6541 hddLog(LOGE, FL("data is null"));
6542 return;
6543 }
6544
6545 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6546#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6547 NULL,
6548#endif
6549 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6550 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6551 GFP_KERNEL);
6552
6553 if (!skb) {
6554 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6555 return;
6556 }
6557
6558 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6559 data->request_id, data->curr_rssi);
6560 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6561 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6562
6563 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6564 data->request_id) ||
6565 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6566 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6567 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6568 data->curr_rssi)) {
6569 hddLog(LOGE, FL("nla put fail"));
6570 goto fail;
6571 }
6572
6573 cfg80211_vendor_event(skb, GFP_KERNEL);
6574 return;
6575
6576fail:
6577 kfree_skb(skb);
6578 return;
6579}
6580
6581
6582
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306583/**
6584 * __wlan_hdd_cfg80211_setband() - set band
6585 * @wiphy: Pointer to wireless phy
6586 * @wdev: Pointer to wireless device
6587 * @data: Pointer to data
6588 * @data_len: Data length
6589 *
6590 * Return: 0 on success, negative errno on failure
6591 */
6592static int
6593__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6594 struct wireless_dev *wdev,
6595 const void *data,
6596 int data_len)
6597{
6598 struct net_device *dev = wdev->netdev;
6599 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6600 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6601 int ret;
6602 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6603 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6604
6605 ENTER();
6606
6607 ret = wlan_hdd_validate_context(hdd_ctx);
6608 if (0 != ret) {
6609 hddLog(LOGE, FL("HDD context is not valid"));
6610 return ret;
6611 }
6612
6613 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6614 policy)) {
6615 hddLog(LOGE, FL("Invalid ATTR"));
6616 return -EINVAL;
6617 }
6618
6619 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6620 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6621 return -EINVAL;
6622 }
6623
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306624 hdd_ctx->isSetBandByNL = TRUE;
6625 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306626 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306627 hdd_ctx->isSetBandByNL = FALSE;
6628
6629 EXIT();
6630 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306631}
6632
6633/**
6634 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6635 * @wiphy: wiphy structure pointer
6636 * @wdev: Wireless device structure pointer
6637 * @data: Pointer to the data received
6638 * @data_len: Length of @data
6639 *
6640 * Return: 0 on success; errno on failure
6641 */
6642static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6643 struct wireless_dev *wdev,
6644 const void *data,
6645 int data_len)
6646{
6647 int ret = 0;
6648
6649 vos_ssr_protect(__func__);
6650 ret = __wlan_hdd_cfg80211_setband(wiphy,
6651 wdev, data, data_len);
6652 vos_ssr_unprotect(__func__);
6653
6654 return ret;
6655}
6656
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306657#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6658/**
6659 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6660 * @hdd_ctx: HDD context
6661 * @request_id: [input] request id
6662 * @pattern_id: [output] pattern id
6663 *
6664 * This function loops through request id to pattern id array
6665 * if the slot is available, store the request id and return pattern id
6666 * if entry exists, return the pattern id
6667 *
6668 * Return: 0 on success and errno on failure
6669 */
6670static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6671 uint32_t request_id,
6672 uint8_t *pattern_id)
6673{
6674 uint32_t i;
6675
6676 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6677 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6678 {
6679 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6680 {
6681 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6682 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6683 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6684 return 0;
6685 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6686 request_id) {
6687 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6688 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6689 return 0;
6690 }
6691 }
6692 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6693 return -EINVAL;
6694}
6695
6696/**
6697 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6698 * @hdd_ctx: HDD context
6699 * @request_id: [input] request id
6700 * @pattern_id: [output] pattern id
6701 *
6702 * This function loops through request id to pattern id array
6703 * reset request id to 0 (slot available again) and
6704 * return pattern id
6705 *
6706 * Return: 0 on success and errno on failure
6707 */
6708static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6709 uint32_t request_id,
6710 uint8_t *pattern_id)
6711{
6712 uint32_t i;
6713
6714 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6715 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6716 {
6717 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6718 {
6719 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6720 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6721 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6722 return 0;
6723 }
6724 }
6725 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6726 return -EINVAL;
6727}
6728
6729
6730/*
6731 * define short names for the global vendor params
6732 * used by __wlan_hdd_cfg80211_offloaded_packets()
6733 */
6734#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6735#define PARAM_REQUEST_ID \
6736 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6737#define PARAM_CONTROL \
6738 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6739#define PARAM_IP_PACKET \
6740 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6741#define PARAM_SRC_MAC_ADDR \
6742 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6743#define PARAM_DST_MAC_ADDR \
6744 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6745#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6746
6747/**
6748 * wlan_hdd_add_tx_ptrn() - add tx pattern
6749 * @adapter: adapter pointer
6750 * @hdd_ctx: hdd context
6751 * @tb: nl attributes
6752 *
6753 * This function reads the NL attributes and forms a AddTxPtrn message
6754 * posts it to SME.
6755 *
6756 */
6757static int
6758wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6759 struct nlattr **tb)
6760{
6761 struct sSirAddPeriodicTxPtrn *add_req;
6762 eHalStatus status;
6763 uint32_t request_id, ret, len;
6764 uint8_t pattern_id = 0;
6765 v_MACADDR_t dst_addr;
6766 uint16_t eth_type = htons(ETH_P_IP);
6767
6768 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6769 {
6770 hddLog(LOGE, FL("Not in Connected state!"));
6771 return -ENOTSUPP;
6772 }
6773
6774 add_req = vos_mem_malloc(sizeof(*add_req));
6775 if (!add_req)
6776 {
6777 hddLog(LOGE, FL("memory allocation failed"));
6778 return -ENOMEM;
6779 }
6780
6781 /* Parse and fetch request Id */
6782 if (!tb[PARAM_REQUEST_ID])
6783 {
6784 hddLog(LOGE, FL("attr request id failed"));
6785 goto fail;
6786 }
6787
6788 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6789 hddLog(LOG1, FL("Request Id: %u"), request_id);
6790 if (request_id == 0)
6791 {
6792 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306793 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306794 }
6795
6796 if (!tb[PARAM_PERIOD])
6797 {
6798 hddLog(LOGE, FL("attr period failed"));
6799 goto fail;
6800 }
6801 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6802 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6803 if (add_req->usPtrnIntervalMs == 0)
6804 {
6805 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6806 goto fail;
6807 }
6808
6809 if (!tb[PARAM_SRC_MAC_ADDR])
6810 {
6811 hddLog(LOGE, FL("attr source mac address failed"));
6812 goto fail;
6813 }
6814 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6815 VOS_MAC_ADDR_SIZE);
6816 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6817 MAC_ADDR_ARRAY(add_req->macAddress));
6818
6819 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6820 VOS_MAC_ADDR_SIZE))
6821 {
6822 hddLog(LOGE,
6823 FL("input src mac address and connected ap bssid are different"));
6824 goto fail;
6825 }
6826
6827 if (!tb[PARAM_DST_MAC_ADDR])
6828 {
6829 hddLog(LOGE, FL("attr dst mac address failed"));
6830 goto fail;
6831 }
6832 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6833 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6834 MAC_ADDR_ARRAY(dst_addr.bytes));
6835
6836 if (!tb[PARAM_IP_PACKET])
6837 {
6838 hddLog(LOGE, FL("attr ip packet failed"));
6839 goto fail;
6840 }
6841 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6842 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6843
6844 if (add_req->ucPtrnSize < 0 ||
6845 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6846 HDD_ETH_HEADER_LEN))
6847 {
6848 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6849 add_req->ucPtrnSize);
6850 goto fail;
6851 }
6852
6853 len = 0;
6854 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6855 len += VOS_MAC_ADDR_SIZE;
6856 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6857 VOS_MAC_ADDR_SIZE);
6858 len += VOS_MAC_ADDR_SIZE;
6859 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6860 len += 2;
6861
6862 /*
6863 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6864 * ------------------------------------------------------------
6865 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6866 * ------------------------------------------------------------
6867 */
6868 vos_mem_copy(&add_req->ucPattern[len],
6869 nla_data(tb[PARAM_IP_PACKET]),
6870 add_req->ucPtrnSize);
6871 add_req->ucPtrnSize += len;
6872
6873 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6874 add_req->ucPattern, add_req->ucPtrnSize);
6875
6876 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6877 if (ret)
6878 {
6879 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6880 goto fail;
6881 }
6882 add_req->ucPtrnId = pattern_id;
6883 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6884
6885 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6886 if (!HAL_STATUS_SUCCESS(status))
6887 {
6888 hddLog(LOGE,
6889 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6890 goto fail;
6891 }
6892
6893 EXIT();
6894 vos_mem_free(add_req);
6895 return 0;
6896
6897fail:
6898 vos_mem_free(add_req);
6899 return -EINVAL;
6900}
6901
6902/**
6903 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6904 * @adapter: adapter pointer
6905 * @hdd_ctx: hdd context
6906 * @tb: nl attributes
6907 *
6908 * This function reads the NL attributes and forms a DelTxPtrn message
6909 * posts it to SME.
6910 *
6911 */
6912static int
6913wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6914 struct nlattr **tb)
6915{
6916 struct sSirDelPeriodicTxPtrn *del_req;
6917 eHalStatus status;
6918 uint32_t request_id, ret;
6919 uint8_t pattern_id = 0;
6920
6921 /* Parse and fetch request Id */
6922 if (!tb[PARAM_REQUEST_ID])
6923 {
6924 hddLog(LOGE, FL("attr request id failed"));
6925 return -EINVAL;
6926 }
6927 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6928 if (request_id == 0)
6929 {
6930 hddLog(LOGE, FL("request_id cannot be zero"));
6931 return -EINVAL;
6932 }
6933
6934 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6935 if (ret)
6936 {
6937 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6938 return -EINVAL;
6939 }
6940
6941 del_req = vos_mem_malloc(sizeof(*del_req));
6942 if (!del_req)
6943 {
6944 hddLog(LOGE, FL("memory allocation failed"));
6945 return -ENOMEM;
6946 }
6947
6948 vos_mem_set(del_req, sizeof(*del_req), 0);
6949 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6950 VOS_MAC_ADDR_SIZE);
6951 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6952 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6953 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6954 request_id, pattern_id, del_req->ucPatternIdBitmap);
6955
6956 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6957 if (!HAL_STATUS_SUCCESS(status))
6958 {
6959 hddLog(LOGE,
6960 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6961 goto fail;
6962 }
6963
6964 EXIT();
6965 vos_mem_free(del_req);
6966 return 0;
6967
6968fail:
6969 vos_mem_free(del_req);
6970 return -EINVAL;
6971}
6972
6973
6974/**
6975 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6976 * @wiphy: Pointer to wireless phy
6977 * @wdev: Pointer to wireless device
6978 * @data: Pointer to data
6979 * @data_len: Data length
6980 *
6981 * Return: 0 on success, negative errno on failure
6982 */
6983static int
6984__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6985 struct wireless_dev *wdev,
6986 const void *data,
6987 int data_len)
6988{
6989 struct net_device *dev = wdev->netdev;
6990 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6991 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6992 struct nlattr *tb[PARAM_MAX + 1];
6993 uint8_t control;
6994 int ret;
6995 static const struct nla_policy policy[PARAM_MAX + 1] =
6996 {
6997 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6998 [PARAM_CONTROL] = { .type = NLA_U32 },
6999 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7000 .len = VOS_MAC_ADDR_SIZE },
7001 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7002 .len = VOS_MAC_ADDR_SIZE },
7003 [PARAM_PERIOD] = { .type = NLA_U32 },
7004 };
7005
7006 ENTER();
7007
7008 ret = wlan_hdd_validate_context(hdd_ctx);
7009 if (0 != ret)
7010 {
7011 hddLog(LOGE, FL("HDD context is not valid"));
7012 return ret;
7013 }
7014
7015 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7016 {
7017 hddLog(LOGE,
7018 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7019 return -ENOTSUPP;
7020 }
7021
7022 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7023 {
7024 hddLog(LOGE, FL("Invalid ATTR"));
7025 return -EINVAL;
7026 }
7027
7028 if (!tb[PARAM_CONTROL])
7029 {
7030 hddLog(LOGE, FL("attr control failed"));
7031 return -EINVAL;
7032 }
7033 control = nla_get_u32(tb[PARAM_CONTROL]);
7034 hddLog(LOG1, FL("Control: %d"), control);
7035
7036 if (control == WLAN_START_OFFLOADED_PACKETS)
7037 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7038 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7039 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7040 else
7041 {
7042 hddLog(LOGE, FL("Invalid control: %d"), control);
7043 return -EINVAL;
7044 }
7045}
7046
7047/*
7048 * done with short names for the global vendor params
7049 * used by __wlan_hdd_cfg80211_offloaded_packets()
7050 */
7051#undef PARAM_MAX
7052#undef PARAM_REQUEST_ID
7053#undef PARAM_CONTROL
7054#undef PARAM_IP_PACKET
7055#undef PARAM_SRC_MAC_ADDR
7056#undef PARAM_DST_MAC_ADDR
7057#undef PARAM_PERIOD
7058
7059/**
7060 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7061 * @wiphy: wiphy structure pointer
7062 * @wdev: Wireless device structure pointer
7063 * @data: Pointer to the data received
7064 * @data_len: Length of @data
7065 *
7066 * Return: 0 on success; errno on failure
7067 */
7068static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7069 struct wireless_dev *wdev,
7070 const void *data,
7071 int data_len)
7072{
7073 int ret = 0;
7074
7075 vos_ssr_protect(__func__);
7076 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7077 wdev, data, data_len);
7078 vos_ssr_unprotect(__func__);
7079
7080 return ret;
7081}
7082#endif
7083
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307084static const struct
7085nla_policy
7086qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307087 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7088 .type = NLA_BINARY,
7089 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307090};
7091
7092/**
7093 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7094 * get link properties like nss, rate flags and operating frequency for
7095 * the connection with the given peer.
7096 * @wiphy: WIPHY structure pointer
7097 * @wdev: Wireless device structure pointer
7098 * @data: Pointer to the data received
7099 * @data_len: Length of the data received
7100 *
7101 * This function return the above link properties on success.
7102 *
7103 * Return: 0 on success and errno on failure
7104 */
7105static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7106 struct wireless_dev *wdev,
7107 const void *data,
7108 int data_len)
7109{
7110 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7111 struct net_device *dev = wdev->netdev;
7112 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7113 hdd_station_ctx_t *hdd_sta_ctx;
7114 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7115 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7116 uint32_t sta_id;
7117 struct sk_buff *reply_skb;
7118 uint32_t rate_flags = 0;
7119 uint8_t nss;
7120 uint8_t final_rate_flags = 0;
7121 uint32_t freq;
7122 v_CONTEXT_t pVosContext = NULL;
7123 ptSapContext pSapCtx = NULL;
7124
7125 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7126 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7127 return -EINVAL;
7128 }
7129
7130 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7131 qca_wlan_vendor_attr_policy)) {
7132 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7133 return -EINVAL;
7134 }
7135
7136 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7137 hddLog(VOS_TRACE_LEVEL_ERROR,
7138 FL("Attribute peerMac not provided for mode=%d"),
7139 adapter->device_mode);
7140 return -EINVAL;
7141 }
7142
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307143 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7144 hddLog(VOS_TRACE_LEVEL_ERROR,
7145 FL("Attribute peerMac is invalid=%d"),
7146 adapter->device_mode);
7147 return -EINVAL;
7148 }
7149
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307150 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7151 sizeof(peer_mac));
7152 hddLog(VOS_TRACE_LEVEL_INFO,
7153 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7154 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7155
7156 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7157 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7158 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7159 if ((hdd_sta_ctx->conn_info.connState !=
7160 eConnectionState_Associated) ||
7161 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7162 VOS_MAC_ADDRESS_LEN)) {
7163 hddLog(VOS_TRACE_LEVEL_ERROR,
7164 FL("Not Associated to mac "MAC_ADDRESS_STR),
7165 MAC_ADDR_ARRAY(peer_mac));
7166 return -EINVAL;
7167 }
7168
7169 nss = 1; //pronto supports only one spatial stream
7170 freq = vos_chan_to_freq(
7171 hdd_sta_ctx->conn_info.operationChannel);
7172 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7173
7174 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7175 adapter->device_mode == WLAN_HDD_SOFTAP) {
7176
7177 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7178 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7179 if(pSapCtx == NULL){
7180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7181 FL("psapCtx is NULL"));
7182 return -ENOENT;
7183 }
7184
7185
7186 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7187 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7188 !vos_is_macaddr_broadcast(
7189 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7190 vos_mem_compare(
7191 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7192 peer_mac, VOS_MAC_ADDRESS_LEN))
7193 break;
7194 }
7195
7196 if (WLAN_MAX_STA_COUNT == sta_id) {
7197 hddLog(VOS_TRACE_LEVEL_ERROR,
7198 FL("No active peer with mac="MAC_ADDRESS_STR),
7199 MAC_ADDR_ARRAY(peer_mac));
7200 return -EINVAL;
7201 }
7202
7203 nss = 1; //pronto supports only one spatial stream
7204 freq = vos_chan_to_freq(
7205 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7206 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7207 } else {
7208 hddLog(VOS_TRACE_LEVEL_ERROR,
7209 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7210 MAC_ADDR_ARRAY(peer_mac));
7211 return -EINVAL;
7212 }
7213
7214 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7215 if (rate_flags & eHAL_TX_RATE_VHT80) {
7216 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7217 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7218 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7219 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7220 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7221 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7222 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7223 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7224 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7225 if (rate_flags & eHAL_TX_RATE_HT40)
7226 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7227 }
7228
7229 if (rate_flags & eHAL_TX_RATE_SGI) {
7230 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7231 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7232 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7233 }
7234 }
7235
7236 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7237 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7238
7239 if (NULL == reply_skb) {
7240 hddLog(VOS_TRACE_LEVEL_ERROR,
7241 FL("getLinkProperties: skb alloc failed"));
7242 return -EINVAL;
7243 }
7244
7245 if (nla_put_u8(reply_skb,
7246 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7247 nss) ||
7248 nla_put_u8(reply_skb,
7249 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7250 final_rate_flags) ||
7251 nla_put_u32(reply_skb,
7252 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7253 freq)) {
7254 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7255 kfree_skb(reply_skb);
7256 return -EINVAL;
7257 }
7258
7259 return cfg80211_vendor_cmd_reply(reply_skb);
7260}
7261
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307262#define BEACON_MISS_THRESH_2_4 \
7263 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7264#define BEACON_MISS_THRESH_5_0 \
7265 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307266#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7267#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7268#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7269#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307270#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7271 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307272
7273/**
7274 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7275 * vendor command
7276 *
7277 * @wiphy: wiphy device pointer
7278 * @wdev: wireless device pointer
7279 * @data: Vendor command data buffer
7280 * @data_len: Buffer length
7281 *
7282 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7283 *
7284 * Return: EOK or other error codes.
7285 */
7286
7287static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7288 struct wireless_dev *wdev,
7289 const void *data,
7290 int data_len)
7291{
7292 struct net_device *dev = wdev->netdev;
7293 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7294 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7295 hdd_station_ctx_t *pHddStaCtx;
7296 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7297 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307298 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307299 eHalStatus status;
7300 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307301 uint8_t hb_thresh_val;
7302
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307303 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7304 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7305 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307306 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7307 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7308 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307309 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7310 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307311 };
7312
7313 ENTER();
7314
7315 if (VOS_FTM_MODE == hdd_get_conparam()) {
7316 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7317 return -EINVAL;
7318 }
7319
7320 ret_val = wlan_hdd_validate_context(pHddCtx);
7321 if (ret_val) {
7322 return ret_val;
7323 }
7324
7325 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7326
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307327 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7328 hddLog(LOGE, FL("Invalid ATTR"));
7329 return -EINVAL;
7330 }
7331
7332 /* check the Wifi Capability */
7333 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7334 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7335 {
7336 hddLog(VOS_TRACE_LEVEL_ERROR,
7337 FL("WIFICONFIG not supported by Firmware"));
7338 return -EINVAL;
7339 }
7340
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307341 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7342 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7343 modifyRoamParamsReq.value =
7344 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7345
7346 if (eHAL_STATUS_SUCCESS !=
7347 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7348 {
7349 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7350 ret_val = -EINVAL;
7351 }
7352 return ret_val;
7353 }
7354
7355 /* Moved this down in order to provide provision to set beacon
7356 * miss penalty count irrespective of connection state.
7357 */
7358 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7359 hddLog(LOGE, FL("Not in Connected state!"));
7360 return -ENOTSUPP;
7361 }
7362
7363 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307364
7365 if (!pReq) {
7366 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7367 "%s: Not able to allocate memory for tSetWifiConfigParams",
7368 __func__);
7369 return eHAL_STATUS_E_MALLOC_FAILED;
7370 }
7371
7372 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7373
7374 pReq->sessionId = pAdapter->sessionId;
7375 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7376
7377 if (tb[PARAM_MODULATED_DTIM]) {
7378 pReq->paramValue = nla_get_u32(
7379 tb[PARAM_MODULATED_DTIM]);
7380 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7381 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307382 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307383 hdd_set_pwrparams(pHddCtx);
7384 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7385 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7386
7387 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7388 iw_full_power_cbfn, pAdapter,
7389 eSME_FULL_PWR_NEEDED_BY_HDD);
7390 }
7391 else
7392 {
7393 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7394 }
7395 }
7396
7397 if (tb[PARAM_STATS_AVG_FACTOR]) {
7398 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7399 pReq->paramValue = nla_get_u16(
7400 tb[PARAM_STATS_AVG_FACTOR]);
7401 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7402 pReq->paramType, pReq->paramValue);
7403 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7404
7405 if (eHAL_STATUS_SUCCESS != status)
7406 {
7407 vos_mem_free(pReq);
7408 pReq = NULL;
7409 ret_val = -EPERM;
7410 return ret_val;
7411 }
7412 }
7413
7414
7415 if (tb[PARAM_GUARD_TIME]) {
7416 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7417 pReq->paramValue = nla_get_u32(
7418 tb[PARAM_GUARD_TIME]);
7419 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7420 pReq->paramType, pReq->paramValue);
7421 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7422
7423 if (eHAL_STATUS_SUCCESS != status)
7424 {
7425 vos_mem_free(pReq);
7426 pReq = NULL;
7427 ret_val = -EPERM;
7428 return ret_val;
7429 }
7430
7431 }
7432
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307433 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7434 hb_thresh_val = nla_get_u8(
7435 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7436
7437 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7438 hb_thresh_val);
7439 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7440 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7441 NULL, eANI_BOOLEAN_FALSE);
7442
7443 status = sme_update_hb_threshold(
7444 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7445 WNI_CFG_HEART_BEAT_THRESHOLD,
7446 hb_thresh_val, eCSR_BAND_24);
7447 if (eHAL_STATUS_SUCCESS != status) {
7448 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7449 vos_mem_free(pReq);
7450 pReq = NULL;
7451 return -EPERM;
7452 }
7453 }
7454
7455 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7456 hb_thresh_val = nla_get_u8(
7457 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7458
7459 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
7460 hb_thresh_val);
7461 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7462 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7463 NULL, eANI_BOOLEAN_FALSE);
7464
7465 status = sme_update_hb_threshold(
7466 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7467 WNI_CFG_HEART_BEAT_THRESHOLD,
7468 hb_thresh_val, eCSR_BAND_5G);
7469 if (eHAL_STATUS_SUCCESS != status) {
7470 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7471 vos_mem_free(pReq);
7472 pReq = NULL;
7473 return -EPERM;
7474 }
7475 }
7476
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307477 EXIT();
7478 return ret_val;
7479}
7480
7481/**
7482 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7483 * vendor command
7484 *
7485 * @wiphy: wiphy device pointer
7486 * @wdev: wireless device pointer
7487 * @data: Vendor command data buffer
7488 * @data_len: Buffer length
7489 *
7490 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7491 *
7492 * Return: EOK or other error codes.
7493 */
7494static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7495 struct wireless_dev *wdev,
7496 const void *data,
7497 int data_len)
7498{
7499 int ret;
7500
7501 vos_ssr_protect(__func__);
7502 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7503 data, data_len);
7504 vos_ssr_unprotect(__func__);
7505
7506 return ret;
7507}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307508
7509/*
7510 * define short names for the global vendor params
7511 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7512 */
7513#define STATS_SET_INVALID \
7514 QCA_ATTR_NUD_STATS_SET_INVALID
7515#define STATS_SET_START \
7516 QCA_ATTR_NUD_STATS_SET_START
7517#define STATS_GW_IPV4 \
7518 QCA_ATTR_NUD_STATS_GW_IPV4
7519#define STATS_SET_MAX \
7520 QCA_ATTR_NUD_STATS_SET_MAX
7521
7522const struct nla_policy
7523qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
7524{
7525 [STATS_SET_START] = {.type = NLA_FLAG },
7526 [STATS_GW_IPV4] = {.type = NLA_U32 },
7527};
7528
7529/**
7530 * hdd_set_nud_stats_cb() - hdd callback api to get status
7531 * @data: pointer to adapter
7532 * @rsp: status
7533 *
7534 * Return: None
7535 */
7536static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
7537{
7538
7539 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7540
7541 if (NULL == adapter)
7542 return;
7543
7544 if (VOS_STATUS_SUCCESS == rsp) {
7545 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7546 "%s success received STATS_SET_START", __func__);
7547 } else {
7548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7549 "%s STATS_SET_START Failed!!", __func__);
7550 }
7551 return;
7552}
7553
7554/**
7555 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7556 * @wiphy: pointer to wireless wiphy structure.
7557 * @wdev: pointer to wireless_dev structure.
7558 * @data: pointer to apfind configuration data.
7559 * @data_len: the length in byte of apfind data.
7560 *
7561 * This is called when wlan driver needs to send arp stats to
7562 * firmware.
7563 *
7564 * Return: An error code or 0 on success.
7565 */
7566static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7567 struct wireless_dev *wdev,
7568 const void *data, int data_len)
7569{
7570 struct nlattr *tb[STATS_SET_MAX + 1];
7571 struct net_device *dev = wdev->netdev;
7572 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7573 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05307574 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307575 setArpStatsParams arp_stats_params;
7576 int err = 0;
7577
7578 ENTER();
7579
7580 err = wlan_hdd_validate_context(hdd_ctx);
7581 if (0 != err)
7582 return err;
7583
7584 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
7585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7586 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
7587 return -EINVAL;
7588 }
7589
7590 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
7591 qca_wlan_vendor_set_nud_stats);
7592 if (err)
7593 {
7594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7595 "%s STATS_SET_START ATTR", __func__);
7596 return err;
7597 }
7598
7599 if (tb[STATS_SET_START])
7600 {
7601 if (!tb[STATS_GW_IPV4]) {
7602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7603 "%s STATS_SET_START CMD", __func__);
7604 return -EINVAL;
7605 }
7606 arp_stats_params.flag = true;
7607 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
7608 } else {
7609 arp_stats_params.flag = false;
7610 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05307611 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7613 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05307614 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
7615 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307616
7617 arp_stats_params.pkt_type = 1; // ARP packet type
7618
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05307619 if (arp_stats_params.flag) {
7620 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
7621 WLANTL_SetARPFWDatapath(pVosContext, true);
7622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7623 "%s Set FW in data path for ARP with tgt IP :%d",
7624 __func__, hdd_ctx->track_arp_ip);
7625 }
7626 else {
7627 WLANTL_SetARPFWDatapath(pVosContext, false);
7628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7629 "%s Remove FW from data path", __func__);
7630 }
7631
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307632 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
7633 arp_stats_params.data_ctx = adapter;
7634
7635 if (eHAL_STATUS_SUCCESS !=
7636 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
7637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7638 "%s STATS_SET_START CMD Failed!!", __func__);
7639 return -EINVAL;
7640 }
7641
7642 EXIT();
7643
7644 return err;
7645}
7646
7647/**
7648 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7649 * @wiphy: pointer to wireless wiphy structure.
7650 * @wdev: pointer to wireless_dev structure.
7651 * @data: pointer to apfind configuration data.
7652 * @data_len: the length in byte of apfind data.
7653 *
7654 * This is called when wlan driver needs to send arp stats to
7655 * firmware.
7656 *
7657 * Return: An error code or 0 on success.
7658 */
7659static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7660 struct wireless_dev *wdev,
7661 const void *data, int data_len)
7662{
7663 int ret;
7664
7665 vos_ssr_protect(__func__);
7666 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
7667 vos_ssr_unprotect(__func__);
7668
7669 return ret;
7670}
7671#undef STATS_SET_INVALID
7672#undef STATS_SET_START
7673#undef STATS_GW_IPV4
7674#undef STATS_SET_MAX
7675
7676/*
7677 * define short names for the global vendor params
7678 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7679 */
7680#define STATS_GET_INVALID \
7681 QCA_ATTR_NUD_STATS_SET_INVALID
7682#define COUNT_FROM_NETDEV \
7683 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
7684#define COUNT_TO_LOWER_MAC \
7685 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
7686#define RX_COUNT_BY_LOWER_MAC \
7687 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
7688#define COUNT_TX_SUCCESS \
7689 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
7690#define RSP_RX_COUNT_BY_LOWER_MAC \
7691 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
7692#define RSP_RX_COUNT_BY_UPPER_MAC \
7693 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
7694#define RSP_COUNT_TO_NETDEV \
7695 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
7696#define RSP_COUNT_OUT_OF_ORDER_DROP \
7697 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
7698#define AP_LINK_ACTIVE \
7699 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
7700#define AP_LINK_DAD \
7701 QCA_ATTR_NUD_STATS_AP_LINK_DAD
7702#define STATS_GET_MAX \
7703 QCA_ATTR_NUD_STATS_GET_MAX
7704
7705const struct nla_policy
7706qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
7707{
7708 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
7709 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
7710 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
7711 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
7712 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
7713 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
7714 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
7715 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
7716 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
7717 [AP_LINK_DAD] = {.type = NLA_FLAG },
7718};
7719
7720static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
7721{
7722
7723 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7724 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7725 struct hdd_nud_stats_context *context;
7726 int status;
7727
7728 ENTER();
7729
7730 if (NULL == adapter)
7731 return;
7732
7733 status = wlan_hdd_validate_context(hdd_ctx);
7734 if (0 != status) {
7735 return;
7736 }
7737
7738 if (!rsp) {
7739 hddLog(LOGE, FL("data is null"));
7740 return;
7741 }
7742
7743 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
7744 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
7745 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
7746 adapter->dad |= rsp->dad;
7747
7748 spin_lock(&hdd_context_lock);
7749 context = &hdd_ctx->nud_stats_context;
7750 complete(&context->response_event);
7751 spin_unlock(&hdd_context_lock);
7752
7753 return;
7754}
7755static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
7756 struct wireless_dev *wdev,
7757 const void *data, int data_len)
7758{
7759 int err = 0;
7760 unsigned long rc;
7761 struct hdd_nud_stats_context *context;
7762 struct net_device *dev = wdev->netdev;
7763 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7764 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7765 getArpStatsParams arp_stats_params;
7766 struct sk_buff *skb;
7767
7768 ENTER();
7769
7770 err = wlan_hdd_validate_context(hdd_ctx);
7771 if (0 != err)
7772 return err;
7773
7774 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
7775 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
7776 arp_stats_params.data_ctx = adapter;
7777
7778 spin_lock(&hdd_context_lock);
7779 context = &hdd_ctx->nud_stats_context;
7780 INIT_COMPLETION(context->response_event);
7781 spin_unlock(&hdd_context_lock);
7782
7783 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
7784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7785 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
7786 return -EINVAL;
7787 }
7788
7789 if (eHAL_STATUS_SUCCESS !=
7790 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
7791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7792 "%s STATS_SET_START CMD Failed!!", __func__);
7793 return -EINVAL;
7794 }
7795
7796 rc = wait_for_completion_timeout(&context->response_event,
7797 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
7798 if (!rc)
7799 {
7800 hddLog(LOGE,
7801 FL("Target response timed out request "));
7802 return -ETIMEDOUT;
7803 }
7804
7805 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7806 WLAN_NUD_STATS_LEN);
7807 if (!skb)
7808 {
7809 hddLog(VOS_TRACE_LEVEL_ERROR,
7810 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
7811 __func__);
7812 return -ENOMEM;
7813 }
7814
7815 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
7816 adapter->hdd_stats.hddArpStats.txCount) ||
7817 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
7818 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
7819 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
7820 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
7821 nla_put_u16(skb, COUNT_TX_SUCCESS,
7822 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
7823 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
7824 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
7825 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
7826 adapter->hdd_stats.hddArpStats.rxCount) ||
7827 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
7828 adapter->hdd_stats.hddArpStats.rxDelivered) ||
7829 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
7830 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
7831 hddLog(LOGE, FL("nla put fail"));
7832 kfree_skb(skb);
7833 return -EINVAL;
7834 }
7835 if (adapter->con_status)
7836 nla_put_flag(skb, AP_LINK_ACTIVE);
7837 if (adapter->dad)
7838 nla_put_flag(skb, AP_LINK_DAD);
7839
7840 cfg80211_vendor_cmd_reply(skb);
7841 return err;
7842}
7843
7844static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
7845 struct wireless_dev *wdev,
7846 const void *data, int data_len)
7847{
7848 int ret;
7849
7850 vos_ssr_protect(__func__);
7851 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
7852 vos_ssr_unprotect(__func__);
7853
7854 return ret;
7855}
7856
7857#undef QCA_ATTR_NUD_STATS_SET_INVALID
7858#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
7859#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
7860#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
7861#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
7862#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
7863#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
7864#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
7865#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
7866#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
7867#undef QCA_ATTR_NUD_STATS_GET_MAX
7868
7869
7870
Kapil Guptaee33bf12016-12-20 18:27:37 +05307871#ifdef WLAN_FEATURE_APFIND
7872/**
7873 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7874 * @wiphy: pointer to wireless wiphy structure.
7875 * @wdev: pointer to wireless_dev structure.
7876 * @data: pointer to apfind configuration data.
7877 * @data_len: the length in byte of apfind data.
7878 *
7879 * This is called when wlan driver needs to send APFIND configurations to
7880 * firmware.
7881 *
7882 * Return: An error code or 0 on success.
7883 */
7884static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7885 struct wireless_dev *wdev,
7886 const void *data, int data_len)
7887{
7888 struct sme_ap_find_request_req apfind_req;
7889 VOS_STATUS status;
7890 int ret_val;
7891 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7892
7893 ENTER();
7894
7895 ret_val = wlan_hdd_validate_context(hdd_ctx);
7896 if (ret_val)
7897 return ret_val;
7898
7899 if (VOS_FTM_MODE == hdd_get_conparam()) {
7900 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7901 return -EPERM;
7902 }
7903
7904 apfind_req.request_data_len = data_len;
7905 apfind_req.request_data = data;
7906
7907 status = sme_apfind_set_cmd(&apfind_req);
7908 if (VOS_STATUS_SUCCESS != status) {
7909 ret_val = -EIO;
7910 }
7911 return ret_val;
7912}
7913
7914/**
7915 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7916 * @wiphy: pointer to wireless wiphy structure.
7917 * @wdev: pointer to wireless_dev structure.
7918 * @data: pointer to apfind configuration data.
7919 * @data_len: the length in byte of apfind data.
7920 *
7921 * This is called when wlan driver needs to send APFIND configurations to
7922 * firmware.
7923 *
7924 * Return: An error code or 0 on success.
7925 */
7926static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7927 struct wireless_dev *wdev,
7928 const void *data, int data_len)
7929{
7930 int ret;
7931
7932 vos_ssr_protect(__func__);
7933 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
7934 vos_ssr_unprotect(__func__);
7935
7936 return ret;
7937}
7938#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307939const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7940{
Mukul Sharma2a271632014-10-13 14:59:01 +05307941 {
7942 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7943 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7944 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7945 WIPHY_VENDOR_CMD_NEED_NETDEV |
7946 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307947 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307948 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307949
7950 {
7951 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7952 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7953 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7954 WIPHY_VENDOR_CMD_NEED_NETDEV |
7955 WIPHY_VENDOR_CMD_NEED_RUNNING,
7956 .doit = wlan_hdd_cfg80211_nan_request
7957 },
7958
Sunil Duttc69bccb2014-05-26 21:30:20 +05307959#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7960 {
7961 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7962 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7963 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7964 WIPHY_VENDOR_CMD_NEED_NETDEV |
7965 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307966 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307967 },
7968
7969 {
7970 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7971 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7972 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7973 WIPHY_VENDOR_CMD_NEED_NETDEV |
7974 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307975 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307976 },
7977
7978 {
7979 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7980 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7981 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7982 WIPHY_VENDOR_CMD_NEED_NETDEV |
7983 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307984 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307985 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307986#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307987#ifdef WLAN_FEATURE_EXTSCAN
7988 {
7989 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7990 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7991 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7992 WIPHY_VENDOR_CMD_NEED_NETDEV |
7993 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307994 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307995 },
7996 {
7997 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7998 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7999 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8000 WIPHY_VENDOR_CMD_NEED_NETDEV |
8001 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308002 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308003 },
8004 {
8005 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8006 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8007 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8008 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308009 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308010 },
8011 {
8012 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8013 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8014 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8015 WIPHY_VENDOR_CMD_NEED_NETDEV |
8016 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308017 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308018 },
8019 {
8020 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8021 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8022 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8023 WIPHY_VENDOR_CMD_NEED_NETDEV |
8024 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308025 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308026 },
8027 {
8028 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8029 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8030 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8031 WIPHY_VENDOR_CMD_NEED_NETDEV |
8032 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308033 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308034 },
8035 {
8036 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8037 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8038 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8039 WIPHY_VENDOR_CMD_NEED_NETDEV |
8040 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308041 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308042 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308043#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308044/*EXT TDLS*/
8045 {
8046 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8047 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8048 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8049 WIPHY_VENDOR_CMD_NEED_NETDEV |
8050 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308051 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308052 },
8053 {
8054 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8055 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8056 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8057 WIPHY_VENDOR_CMD_NEED_NETDEV |
8058 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308059 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308060 },
8061 {
8062 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8063 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8064 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8065 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308066 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308067 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308068 {
8069 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8070 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8071 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8072 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308073 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308074 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308075 {
8076 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8077 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8078 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8079 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308080 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308081 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308082 {
8083 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8084 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8085 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8086 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308087 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308088 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308089 {
8090 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8091 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8092 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8093 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308094 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308095 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308096 {
8097 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308098 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8099 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8100 WIPHY_VENDOR_CMD_NEED_NETDEV |
8101 WIPHY_VENDOR_CMD_NEED_RUNNING,
8102 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8103 },
8104 {
8105 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308106 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8107 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8108 WIPHY_VENDOR_CMD_NEED_NETDEV |
8109 WIPHY_VENDOR_CMD_NEED_RUNNING,
8110 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308111 },
8112 {
8113 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8114 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8115 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8116 WIPHY_VENDOR_CMD_NEED_NETDEV,
8117 .doit = wlan_hdd_cfg80211_wifi_logger_start
8118 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308119 {
8120 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8121 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8122 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8123 WIPHY_VENDOR_CMD_NEED_NETDEV|
8124 WIPHY_VENDOR_CMD_NEED_RUNNING,
8125 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308126 },
8127 {
8128 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8129 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8130 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8131 WIPHY_VENDOR_CMD_NEED_NETDEV |
8132 WIPHY_VENDOR_CMD_NEED_RUNNING,
8133 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308134 },
8135 {
8136 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8137 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8138 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8139 WIPHY_VENDOR_CMD_NEED_NETDEV |
8140 WIPHY_VENDOR_CMD_NEED_RUNNING,
8141 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308142 },
8143#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8144 {
8145 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8146 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8147 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8148 WIPHY_VENDOR_CMD_NEED_NETDEV |
8149 WIPHY_VENDOR_CMD_NEED_RUNNING,
8150 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308151 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308152#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308153 {
8154 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8155 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8156 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8157 WIPHY_VENDOR_CMD_NEED_NETDEV |
8158 WIPHY_VENDOR_CMD_NEED_RUNNING,
8159 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308160 },
8161 {
8162 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8163 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8164 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8165 WIPHY_VENDOR_CMD_NEED_NETDEV |
8166 WIPHY_VENDOR_CMD_NEED_RUNNING,
8167 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308168 },
8169#ifdef WLAN_FEATURE_APFIND
8170 {
8171 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8172 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8173 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8174 WIPHY_VENDOR_CMD_NEED_NETDEV,
8175 .doit = wlan_hdd_cfg80211_apfind_cmd
8176 },
8177#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308178 {
8179 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8180 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8181 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8182 WIPHY_VENDOR_CMD_NEED_NETDEV |
8183 WIPHY_VENDOR_CMD_NEED_RUNNING,
8184 .doit = wlan_hdd_cfg80211_set_nud_stats
8185 },
8186 {
8187 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8188 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8189 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8190 WIPHY_VENDOR_CMD_NEED_NETDEV |
8191 WIPHY_VENDOR_CMD_NEED_RUNNING,
8192 .doit = wlan_hdd_cfg80211_get_nud_stats
8193 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308194 {
8195 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8196 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8197 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8198 WIPHY_VENDOR_CMD_NEED_NETDEV |
8199 WIPHY_VENDOR_CMD_NEED_RUNNING,
8200 .doit = hdd_cfg80211_get_station_cmd
8201 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308202};
8203
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008204/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308205static const
8206struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008207{
8208#ifdef FEATURE_WLAN_CH_AVOID
8209 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308210 .vendor_id = QCA_NL80211_VENDOR_ID,
8211 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008212 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308213#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8214#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8215 {
8216 /* Index = 1*/
8217 .vendor_id = QCA_NL80211_VENDOR_ID,
8218 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8219 },
8220 {
8221 /* Index = 2*/
8222 .vendor_id = QCA_NL80211_VENDOR_ID,
8223 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8224 },
8225 {
8226 /* Index = 3*/
8227 .vendor_id = QCA_NL80211_VENDOR_ID,
8228 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8229 },
8230 {
8231 /* Index = 4*/
8232 .vendor_id = QCA_NL80211_VENDOR_ID,
8233 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8234 },
8235 {
8236 /* Index = 5*/
8237 .vendor_id = QCA_NL80211_VENDOR_ID,
8238 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8239 },
8240 {
8241 /* Index = 6*/
8242 .vendor_id = QCA_NL80211_VENDOR_ID,
8243 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8244 },
8245#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308246#ifdef WLAN_FEATURE_EXTSCAN
8247 {
8248 .vendor_id = QCA_NL80211_VENDOR_ID,
8249 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8250 },
8251 {
8252 .vendor_id = QCA_NL80211_VENDOR_ID,
8253 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8254 },
8255 {
8256 .vendor_id = QCA_NL80211_VENDOR_ID,
8257 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8258 },
8259 {
8260 .vendor_id = QCA_NL80211_VENDOR_ID,
8261 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8262 },
8263 {
8264 .vendor_id = QCA_NL80211_VENDOR_ID,
8265 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8266 },
8267 {
8268 .vendor_id = QCA_NL80211_VENDOR_ID,
8269 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8270 },
8271 {
8272 .vendor_id = QCA_NL80211_VENDOR_ID,
8273 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8274 },
8275 {
8276 .vendor_id = QCA_NL80211_VENDOR_ID,
8277 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8278 },
8279 {
8280 .vendor_id = QCA_NL80211_VENDOR_ID,
8281 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8282 },
8283 {
8284 .vendor_id = QCA_NL80211_VENDOR_ID,
8285 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8286 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308287#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308288/*EXT TDLS*/
8289 {
8290 .vendor_id = QCA_NL80211_VENDOR_ID,
8291 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8292 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308293 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8294 .vendor_id = QCA_NL80211_VENDOR_ID,
8295 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8296 },
8297
Srinivas Dasari030bad32015-02-18 23:23:54 +05308298
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308299 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308300 .vendor_id = QCA_NL80211_VENDOR_ID,
8301 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8302 },
8303
Sushant Kaushik084f6592015-09-10 13:11:56 +05308304 {
8305 .vendor_id = QCA_NL80211_VENDOR_ID,
8306 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308307 },
8308 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8309 .vendor_id = QCA_NL80211_VENDOR_ID,
8310 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8311 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308312 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8313 .vendor_id = QCA_NL80211_VENDOR_ID,
8314 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8315 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308316 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8317 .vendor_id = QCA_NL80211_VENDOR_ID,
8318 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8319 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008320};
8321
Jeff Johnson295189b2012-06-20 16:38:30 -07008322/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308323 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308324 * This function is called by hdd_wlan_startup()
8325 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308326 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008327 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308328struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008329{
8330 struct wiphy *wiphy;
8331 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308332 /*
8333 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008334 */
8335 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8336
8337 if (!wiphy)
8338 {
8339 /* Print error and jump into err label and free the memory */
8340 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8341 return NULL;
8342 }
8343
Sunil Duttc69bccb2014-05-26 21:30:20 +05308344
Jeff Johnson295189b2012-06-20 16:38:30 -07008345 return wiphy;
8346}
8347
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308348#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8349 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8350/**
8351 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8352 * @wiphy: pointer to wiphy
8353 * @config: pointer to config
8354 *
8355 * Return: None
8356 */
8357static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8358 hdd_config_t *config)
8359{
8360 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8361 if (config->max_sched_scan_plan_interval)
8362 wiphy->max_sched_scan_plan_interval =
8363 config->max_sched_scan_plan_interval;
8364 if (config->max_sched_scan_plan_iterations)
8365 wiphy->max_sched_scan_plan_iterations =
8366 config->max_sched_scan_plan_iterations;
8367}
8368#else
8369static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8370 hdd_config_t *config)
8371{
8372}
8373#endif
8374
Jeff Johnson295189b2012-06-20 16:38:30 -07008375/*
8376 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308377 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008378 * private ioctl to change the band value
8379 */
8380int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8381{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308382 int i, j;
8383 eNVChannelEnabledType channelEnabledState;
8384
Jeff Johnsone7245742012-09-05 17:12:55 -07008385 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308386
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308387 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008388 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308389
8390 if (NULL == wiphy->bands[i])
8391 {
8392 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8393 __func__, i);
8394 continue;
8395 }
8396
8397 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8398 {
8399 struct ieee80211_supported_band *band = wiphy->bands[i];
8400
8401 channelEnabledState = vos_nv_getChannelEnabledState(
8402 band->channels[j].hw_value);
8403
8404 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
8405 {
Abhishek Singh678227a2014-11-04 10:52:38 +05308406 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308407 continue;
8408 }
8409 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
8410 {
8411 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8412 continue;
8413 }
8414
8415 if (NV_CHANNEL_DISABLE == channelEnabledState ||
8416 NV_CHANNEL_INVALID == channelEnabledState)
8417 {
8418 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8419 }
8420 else if (NV_CHANNEL_DFS == channelEnabledState)
8421 {
8422 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8423 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
8424 }
8425 else
8426 {
8427 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
8428 |IEEE80211_CHAN_RADAR);
8429 }
8430 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008431 }
8432 return 0;
8433}
8434/*
8435 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308436 * This function is called by hdd_wlan_startup()
8437 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008438 * This function is used to initialize and register wiphy structure.
8439 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308440int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008441 struct wiphy *wiphy,
8442 hdd_config_t *pCfg
8443 )
8444{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308445 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308446 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8447
Jeff Johnsone7245742012-09-05 17:12:55 -07008448 ENTER();
8449
Jeff Johnson295189b2012-06-20 16:38:30 -07008450 /* Now bind the underlying wlan device with wiphy */
8451 set_wiphy_dev(wiphy, dev);
8452
8453 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008454
Kiet Lam6c583332013-10-14 05:37:09 +05308455#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008456 /* the flag for the other case would be initialzed in
8457 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05308458#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8459 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
8460#else
Amar Singhal0a402232013-10-11 20:57:16 -07008461 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05308462#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05308463#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008464
Amar Singhalfddc28c2013-09-05 13:03:40 -07008465 /* This will disable updating of NL channels from passive to
8466 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308467#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8468 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
8469#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07008470 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308471#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07008472
Amar Singhala49cbc52013-10-08 18:37:44 -07008473
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008474#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008475 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
8476 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
8477 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07008478 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308479#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05308480 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308481#else
8482 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
8483#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008484#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008485
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008486#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008487 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08008488#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008489 || pCfg->isFastRoamIniFeatureEnabled
8490#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008491#ifdef FEATURE_WLAN_ESE
8492 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008493#endif
8494 )
8495 {
8496 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
8497 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08008498#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008499#ifdef FEATURE_WLAN_TDLS
8500 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
8501 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
8502#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308503#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05308504 if (pCfg->configPNOScanSupport)
8505 {
8506 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
8507 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
8508 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
8509 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
8510 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308511#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008512
Abhishek Singh10d85972015-04-17 10:27:23 +05308513#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8514 wiphy->features |= NL80211_FEATURE_HT_IBSS;
8515#endif
8516
Amar Singhalfddc28c2013-09-05 13:03:40 -07008517#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008518 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
8519 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07008520 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008521 driver need to determine what to do with both
8522 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07008523
8524 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07008525#else
8526 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008527#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008528
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308529 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8530
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308531 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008532
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308533 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8534
Jeff Johnson295189b2012-06-20 16:38:30 -07008535 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308536 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8537 | BIT(NL80211_IFTYPE_ADHOC)
8538 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8539 | BIT(NL80211_IFTYPE_P2P_GO)
8540 | BIT(NL80211_IFTYPE_AP);
8541
8542 if (VOS_MONITOR_MODE == hdd_get_conparam())
8543 {
8544 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
8545 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008546
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308547 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008548 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308549#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8550 if( pCfg->enableMCC )
8551 {
8552 /* Currently, supports up to two channels */
8553 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008554
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308555 if( !pCfg->allowMCCGODiffBI )
8556 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008557
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308558 }
8559 wiphy->iface_combinations = &wlan_hdd_iface_combination;
8560 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008561#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308562 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008563
Jeff Johnson295189b2012-06-20 16:38:30 -07008564 /* Before registering we need to update the ht capabilitied based
8565 * on ini values*/
8566 if( !pCfg->ShortGI20MhzEnable )
8567 {
8568 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8569 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008570 }
8571
8572 if( !pCfg->ShortGI40MhzEnable )
8573 {
8574 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8575 }
8576
8577 if( !pCfg->nChannelBondingMode5GHz )
8578 {
8579 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8580 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308581 /*
8582 * In case of static linked driver at the time of driver unload,
8583 * module exit doesn't happens. Module cleanup helps in cleaning
8584 * of static memory.
8585 * If driver load happens statically, at the time of driver unload,
8586 * wiphy flags don't get reset because of static memory.
8587 * It's better not to store channel in static memory.
8588 */
8589 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8590 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8591 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8592 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8593 {
8594 hddLog(VOS_TRACE_LEVEL_ERROR,
8595 FL("Not enough memory to allocate channels"));
8596 return -ENOMEM;
8597 }
8598 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8599 &hdd_channels_2_4_GHZ[0],
8600 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008601
Agrawal Ashish97dec502015-11-26 20:20:58 +05308602 if (true == hdd_is_5g_supported(pHddCtx))
8603 {
8604 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8605 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8606 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8607 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8608 {
8609 hddLog(VOS_TRACE_LEVEL_ERROR,
8610 FL("Not enough memory to allocate channels"));
8611 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8612 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8613 return -ENOMEM;
8614 }
8615 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8616 &hdd_channels_5_GHZ[0],
8617 sizeof(hdd_channels_5_GHZ));
8618 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308619
8620 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8621 {
8622
8623 if (NULL == wiphy->bands[i])
8624 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308625 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308626 __func__, i);
8627 continue;
8628 }
8629
8630 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8631 {
8632 struct ieee80211_supported_band *band = wiphy->bands[i];
8633
8634 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8635 {
8636 // Enable social channels for P2P
8637 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8638 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8639 else
8640 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8641 continue;
8642 }
8643 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8644 {
8645 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8646 continue;
8647 }
8648 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008649 }
8650 /*Initialise the supported cipher suite details*/
8651 wiphy->cipher_suites = hdd_cipher_suites;
8652 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8653
8654 /*signal strength in mBm (100*dBm) */
8655 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8656
8657#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308658 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008659#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008660
Sunil Duttc69bccb2014-05-26 21:30:20 +05308661 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8662 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008663 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8664 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8665
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308666 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
8667
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308668 EXIT();
8669 return 0;
8670}
8671
8672/* In this function we are registering wiphy. */
8673int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8674{
8675 ENTER();
8676 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008677 if (0 > wiphy_register(wiphy))
8678 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308679 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008680 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8681 return -EIO;
8682 }
8683
8684 EXIT();
8685 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308686}
Jeff Johnson295189b2012-06-20 16:38:30 -07008687
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308688/* In this function we are updating channel list when,
8689 regulatory domain is FCC and country code is US.
8690 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8691 As per FCC smart phone is not a indoor device.
8692 GO should not opeate on indoor channels */
8693void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8694{
8695 int j;
8696 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8697 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8698 //Default counrtycode from NV at the time of wiphy initialization.
8699 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8700 &defaultCountryCode[0]))
8701 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008702 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308703 }
8704 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8705 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308706 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8707 {
8708 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8709 return;
8710 }
8711 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8712 {
8713 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8714 // Mark UNII -1 band channel as passive
8715 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8716 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8717 }
8718 }
8719}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308720/* This function registers for all frame which supplicant is interested in */
8721void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008722{
Jeff Johnson295189b2012-06-20 16:38:30 -07008723 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8724 /* Register for all P2P action, public action etc frames */
8725 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008726 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308727 /* Register frame indication call back */
8728 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008729 /* Right now we are registering these frame when driver is getting
8730 initialized. Once we will move to 2.6.37 kernel, in which we have
8731 frame register ops, we will move this code as a part of that */
8732 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308733 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008734 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8735
8736 /* GAS Initial Response */
8737 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8738 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308739
Jeff Johnson295189b2012-06-20 16:38:30 -07008740 /* GAS Comeback Request */
8741 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8742 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8743
8744 /* GAS Comeback Response */
8745 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8746 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8747
8748 /* P2P Public Action */
8749 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308750 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008751 P2P_PUBLIC_ACTION_FRAME_SIZE );
8752
8753 /* P2P Action */
8754 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8755 (v_U8_t*)P2P_ACTION_FRAME,
8756 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008757
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308758 /* WNM BSS Transition Request frame */
8759 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8760 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8761 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008762
8763 /* WNM-Notification */
8764 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8765 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8766 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008767}
8768
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308769void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008770{
Jeff Johnson295189b2012-06-20 16:38:30 -07008771 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8772 /* Register for all P2P action, public action etc frames */
8773 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8774
Jeff Johnsone7245742012-09-05 17:12:55 -07008775 ENTER();
8776
Jeff Johnson295189b2012-06-20 16:38:30 -07008777 /* Right now we are registering these frame when driver is getting
8778 initialized. Once we will move to 2.6.37 kernel, in which we have
8779 frame register ops, we will move this code as a part of that */
8780 /* GAS Initial Request */
8781
8782 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8783 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8784
8785 /* GAS Initial Response */
8786 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8787 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308788
Jeff Johnson295189b2012-06-20 16:38:30 -07008789 /* GAS Comeback Request */
8790 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8791 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8792
8793 /* GAS Comeback Response */
8794 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8795 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8796
8797 /* P2P Public Action */
8798 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308799 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008800 P2P_PUBLIC_ACTION_FRAME_SIZE );
8801
8802 /* P2P Action */
8803 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8804 (v_U8_t*)P2P_ACTION_FRAME,
8805 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008806 /* WNM-Notification */
8807 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8808 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8809 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008810}
8811
8812#ifdef FEATURE_WLAN_WAPI
8813void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308814 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008815{
8816 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8817 tCsrRoamSetKey setKey;
8818 v_BOOL_t isConnected = TRUE;
8819 int status = 0;
8820 v_U32_t roamId= 0xFF;
8821 tANI_U8 *pKeyPtr = NULL;
8822 int n = 0;
8823
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308824 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8825 __func__, hdd_device_modetoString(pAdapter->device_mode),
8826 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008827
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308828 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008829 setKey.keyId = key_index; // Store Key ID
8830 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8831 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8832 setKey.paeRole = 0 ; // the PAE role
8833 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8834 {
8835 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8836 }
8837 else
8838 {
8839 isConnected = hdd_connIsConnected(pHddStaCtx);
8840 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8841 }
8842 setKey.keyLength = key_Len;
8843 pKeyPtr = setKey.Key;
8844 memcpy( pKeyPtr, key, key_Len);
8845
Arif Hussain6d2a3322013-11-17 19:50:10 -08008846 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008847 __func__, key_Len);
8848 for (n = 0 ; n < key_Len; n++)
8849 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8850 __func__,n,setKey.Key[n]);
8851
8852 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8853 if ( isConnected )
8854 {
8855 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8856 pAdapter->sessionId, &setKey, &roamId );
8857 }
8858 if ( status != 0 )
8859 {
8860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8861 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8862 __LINE__, status );
8863 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8864 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308865 /* Need to clear any trace of key value in the memory.
8866 * Thus zero out the memory even though it is local
8867 * variable.
8868 */
8869 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008870}
8871#endif /* FEATURE_WLAN_WAPI*/
8872
8873#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308874int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008875 beacon_data_t **ppBeacon,
8876 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008877#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308878int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008879 beacon_data_t **ppBeacon,
8880 struct cfg80211_beacon_data *params,
8881 int dtim_period)
8882#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308883{
Jeff Johnson295189b2012-06-20 16:38:30 -07008884 int size;
8885 beacon_data_t *beacon = NULL;
8886 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05308887 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
8888 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07008889
Jeff Johnsone7245742012-09-05 17:12:55 -07008890 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008891 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308892 {
8893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8894 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008895 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308896 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008897
8898 old = pAdapter->sessionCtx.ap.beacon;
8899
8900 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308901 {
8902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8903 FL("session(%d) old and new heads points to NULL"),
8904 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008905 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308906 }
8907
8908 if (params->tail && !params->tail_len)
8909 {
8910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8911 FL("tail_len is zero but tail is not NULL"));
8912 return -EINVAL;
8913 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008914
Jeff Johnson295189b2012-06-20 16:38:30 -07008915#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8916 /* Kernel 3.0 is not updating dtim_period for set beacon */
8917 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308918 {
8919 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8920 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008921 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308922 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008923#endif
8924
Kapil Gupta137ef892016-12-13 19:38:00 +05308925 if (params->head)
8926 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008927 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308928 head = params->head;
8929 } else
8930 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008931 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308932 head = old->head;
8933 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008934
Kapil Gupta137ef892016-12-13 19:38:00 +05308935 if (params->tail || !old)
8936 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008937 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308938 tail = params->tail;
8939 } else
8940 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008941 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308942 tail = old->tail;
8943 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008944
Kapil Gupta137ef892016-12-13 19:38:00 +05308945 if (params->proberesp_ies || !old)
8946 {
8947 proberesp_ies_len = params->proberesp_ies_len;
8948 proberesp_ies = params->proberesp_ies;
8949 } else
8950 {
8951 proberesp_ies_len = old->proberesp_ies_len;
8952 proberesp_ies = old->proberesp_ies;
8953 }
8954
8955 if (params->assocresp_ies || !old)
8956 {
8957 assocresp_ies_len = params->assocresp_ies_len;
8958 assocresp_ies = params->assocresp_ies;
8959 } else
8960 {
8961 assocresp_ies_len = old->assocresp_ies_len;
8962 assocresp_ies = old->assocresp_ies;
8963 }
8964
8965 size = sizeof(beacon_data_t) + head_len + tail_len +
8966 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07008967
8968 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008969 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308970 {
8971 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8972 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008973 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308974 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008975
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008976#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05308977 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07008978 beacon->dtim_period = params->dtim_period;
8979 else
8980 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008981#else
Kapil Gupta137ef892016-12-13 19:38:00 +05308982 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008983 beacon->dtim_period = dtim_period;
8984 else
8985 beacon->dtim_period = old->dtim_period;
8986#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308987
Jeff Johnson295189b2012-06-20 16:38:30 -07008988 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8989 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308990 beacon->proberesp_ies = beacon->tail + tail_len;
8991 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
8992
Jeff Johnson295189b2012-06-20 16:38:30 -07008993 beacon->head_len = head_len;
8994 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308995 beacon->proberesp_ies_len = proberesp_ies_len;
8996 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07008997
c_manjee527ecac2017-01-25 12:25:27 +05308998 if (head && head_len)
8999 memcpy(beacon->head, head, head_len);
9000 if (tail && tail_len)
9001 memcpy(beacon->tail, tail, tail_len);
9002 if (proberesp_ies && proberesp_ies_len)
9003 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9004 if (assocresp_ies && assocresp_ies_len)
9005 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009006
9007 *ppBeacon = beacon;
9008
9009 kfree(old);
9010
9011 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009012}
Jeff Johnson295189b2012-06-20 16:38:30 -07009013
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309014v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9015#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9016 const v_U8_t *pIes,
9017#else
9018 v_U8_t *pIes,
9019#endif
9020 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009021{
9022 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309023 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009024 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309025
Jeff Johnson295189b2012-06-20 16:38:30 -07009026 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309027 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009028 elem_id = ptr[0];
9029 elem_len = ptr[1];
9030 left -= 2;
9031 if(elem_len > left)
9032 {
9033 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009034 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009035 eid,elem_len,left);
9036 return NULL;
9037 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309038 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009039 {
9040 return ptr;
9041 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309042
Jeff Johnson295189b2012-06-20 16:38:30 -07009043 left -= elem_len;
9044 ptr += (elem_len + 2);
9045 }
9046 return NULL;
9047}
9048
Jeff Johnson295189b2012-06-20 16:38:30 -07009049/* Check if rate is 11g rate or not */
9050static int wlan_hdd_rate_is_11g(u8 rate)
9051{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009052 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009053 u8 i;
9054 for (i = 0; i < 8; i++)
9055 {
9056 if(rate == gRateArray[i])
9057 return TRUE;
9058 }
9059 return FALSE;
9060}
9061
9062/* Check for 11g rate and set proper 11g only mode */
9063static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9064 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9065{
9066 u8 i, num_rates = pIe[0];
9067
9068 pIe += 1;
9069 for ( i = 0; i < num_rates; i++)
9070 {
9071 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9072 {
9073 /* If rate set have 11g rate than change the mode to 11G */
9074 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9075 if (pIe[i] & BASIC_RATE_MASK)
9076 {
9077 /* If we have 11g rate as basic rate, it means mode
9078 is 11g only mode.
9079 */
9080 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9081 *pCheckRatesfor11g = FALSE;
9082 }
9083 }
9084 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9085 {
9086 *require_ht = TRUE;
9087 }
9088 }
9089 return;
9090}
9091
9092static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9093{
9094 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9095 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9096 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9097 u8 checkRatesfor11g = TRUE;
9098 u8 require_ht = FALSE;
9099 u8 *pIe=NULL;
9100
9101 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9102
9103 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9104 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9105 if (pIe != NULL)
9106 {
9107 pIe += 1;
9108 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9109 &pConfig->SapHw_mode);
9110 }
9111
9112 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9113 WLAN_EID_EXT_SUPP_RATES);
9114 if (pIe != NULL)
9115 {
9116
9117 pIe += 1;
9118 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9119 &pConfig->SapHw_mode);
9120 }
9121
9122 if( pConfig->channel > 14 )
9123 {
9124 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9125 }
9126
9127 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9128 WLAN_EID_HT_CAPABILITY);
9129
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309130 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009131 {
9132 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9133 if(require_ht)
9134 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9135 }
9136}
9137
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309138static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9139 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9140{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009141 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309142 v_U8_t *pIe = NULL;
9143 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9144
9145 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9146 pBeacon->tail, pBeacon->tail_len);
9147
9148 if (pIe)
9149 {
9150 ielen = pIe[1] + 2;
9151 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9152 {
9153 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9154 }
9155 else
9156 {
9157 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9158 return -EINVAL;
9159 }
9160 *total_ielen += ielen;
9161 }
9162 return 0;
9163}
9164
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009165static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9166 v_U8_t *genie, v_U8_t *total_ielen)
9167{
9168 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9169 int left = pBeacon->tail_len;
9170 v_U8_t *ptr = pBeacon->tail;
9171 v_U8_t elem_id, elem_len;
9172 v_U16_t ielen = 0;
9173
9174 if ( NULL == ptr || 0 == left )
9175 return;
9176
9177 while (left >= 2)
9178 {
9179 elem_id = ptr[0];
9180 elem_len = ptr[1];
9181 left -= 2;
9182 if (elem_len > left)
9183 {
9184 hddLog( VOS_TRACE_LEVEL_ERROR,
9185 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9186 elem_id, elem_len, left);
9187 return;
9188 }
9189 if (IE_EID_VENDOR == elem_id)
9190 {
9191 /* skipping the VSIE's which we don't want to include or
9192 * it will be included by existing code
9193 */
9194 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9195#ifdef WLAN_FEATURE_WFD
9196 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9197#endif
9198 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9199 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9200 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9201 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9202 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9203 {
9204 ielen = ptr[1] + 2;
9205 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9206 {
9207 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9208 *total_ielen += ielen;
9209 }
9210 else
9211 {
9212 hddLog( VOS_TRACE_LEVEL_ERROR,
9213 "IE Length is too big "
9214 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9215 elem_id, elem_len, *total_ielen);
9216 }
9217 }
9218 }
9219
9220 left -= elem_len;
9221 ptr += (elem_len + 2);
9222 }
9223 return;
9224}
9225
Kapil Gupta137ef892016-12-13 19:38:00 +05309226int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009227{
9228 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309229 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009230 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009231 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309232 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009233
9234 genie = vos_mem_malloc(MAX_GENIE_LEN);
9235
9236 if(genie == NULL) {
9237
9238 return -ENOMEM;
9239 }
9240
Kapil Gupta137ef892016-12-13 19:38:00 +05309241 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309242 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9243 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009244 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309245 hddLog(LOGE,
9246 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309247 ret = -EINVAL;
9248 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009249 }
9250
9251#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309252 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9253 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9254 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309255 hddLog(LOGE,
9256 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309257 ret = -EINVAL;
9258 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009259 }
9260#endif
9261
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309262 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9263 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009264 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309265 hddLog(LOGE,
9266 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309267 ret = -EINVAL;
9268 goto done;
9269 }
9270
9271 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9272 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009273 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009274 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009275
9276 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9277 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9278 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9279 {
9280 hddLog(LOGE,
9281 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009282 ret = -EINVAL;
9283 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009284 }
9285
9286 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9287 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9288 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9289 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9290 ==eHAL_STATUS_FAILURE)
9291 {
9292 hddLog(LOGE,
9293 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009294 ret = -EINVAL;
9295 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009296 }
9297
9298 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309299 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009300 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309301 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009302 u8 probe_rsp_ie_len[3] = {0};
9303 u8 counter = 0;
9304 /* Check Probe Resp Length if it is greater then 255 then Store
9305 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9306 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9307 Store More then 255 bytes into One Variable.
9308 */
9309 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9310 {
9311 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9312 {
9313 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9314 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9315 }
9316 else
9317 {
9318 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9319 rem_probe_resp_ie_len = 0;
9320 }
9321 }
9322
9323 rem_probe_resp_ie_len = 0;
9324
9325 if (probe_rsp_ie_len[0] > 0)
9326 {
9327 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9328 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309329 (tANI_U8*)&pBeacon->
9330 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009331 probe_rsp_ie_len[0], NULL,
9332 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9333 {
9334 hddLog(LOGE,
9335 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009336 ret = -EINVAL;
9337 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009338 }
9339 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9340 }
9341
9342 if (probe_rsp_ie_len[1] > 0)
9343 {
9344 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9345 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05309346 (tANI_U8*)&pBeacon->
9347 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009348 probe_rsp_ie_len[1], NULL,
9349 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9350 {
9351 hddLog(LOGE,
9352 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009353 ret = -EINVAL;
9354 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009355 }
9356 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9357 }
9358
9359 if (probe_rsp_ie_len[2] > 0)
9360 {
9361 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9362 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05309363 (tANI_U8*)&pBeacon->
9364 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009365 probe_rsp_ie_len[2], NULL,
9366 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9367 {
9368 hddLog(LOGE,
9369 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009370 ret = -EINVAL;
9371 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009372 }
9373 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9374 }
9375
9376 if (probe_rsp_ie_len[1] == 0 )
9377 {
9378 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9379 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9380 eANI_BOOLEAN_FALSE) )
9381 {
9382 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009383 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009384 }
9385 }
9386
9387 if (probe_rsp_ie_len[2] == 0 )
9388 {
9389 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9390 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9391 eANI_BOOLEAN_FALSE) )
9392 {
9393 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009394 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009395 }
9396 }
9397
9398 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9399 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9400 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9401 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9402 == eHAL_STATUS_FAILURE)
9403 {
9404 hddLog(LOGE,
9405 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009406 ret = -EINVAL;
9407 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009408 }
9409 }
9410 else
9411 {
9412 // Reset WNI_CFG_PROBE_RSP Flags
9413 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
9414
9415 hddLog(VOS_TRACE_LEVEL_INFO,
9416 "%s: No Probe Response IE received in set beacon",
9417 __func__);
9418 }
9419
9420 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309421 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009422 {
9423 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05309424 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
9425 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07009426 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9427 {
9428 hddLog(LOGE,
9429 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009430 ret = -EINVAL;
9431 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009432 }
9433
9434 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9435 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
9436 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9437 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9438 == eHAL_STATUS_FAILURE)
9439 {
9440 hddLog(LOGE,
9441 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009442 ret = -EINVAL;
9443 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009444 }
9445 }
9446 else
9447 {
9448 hddLog(VOS_TRACE_LEVEL_INFO,
9449 "%s: No Assoc Response IE received in set beacon",
9450 __func__);
9451
9452 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9453 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9454 eANI_BOOLEAN_FALSE) )
9455 {
9456 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009457 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009458 }
9459 }
9460
Jeff Johnsone7245742012-09-05 17:12:55 -07009461done:
Jeff Johnson295189b2012-06-20 16:38:30 -07009462 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309463 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009464}
Jeff Johnson295189b2012-06-20 16:38:30 -07009465
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309466/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009467 * FUNCTION: wlan_hdd_validate_operation_channel
9468 * called by wlan_hdd_cfg80211_start_bss() and
9469 * wlan_hdd_cfg80211_set_channel()
9470 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309471 * channel list.
9472 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07009473VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009474{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309475
Jeff Johnson295189b2012-06-20 16:38:30 -07009476 v_U32_t num_ch = 0;
9477 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
9478 u32 indx = 0;
9479 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309480 v_U8_t fValidChannel = FALSE, count = 0;
9481 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309482
Jeff Johnson295189b2012-06-20 16:38:30 -07009483 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9484
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309485 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009486 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309487 /* Validate the channel */
9488 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009489 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309490 if ( channel == rfChannels[count].channelNum )
9491 {
9492 fValidChannel = TRUE;
9493 break;
9494 }
9495 }
9496 if (fValidChannel != TRUE)
9497 {
9498 hddLog(VOS_TRACE_LEVEL_ERROR,
9499 "%s: Invalid Channel [%d]", __func__, channel);
9500 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009501 }
9502 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309503 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009504 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309505 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
9506 valid_ch, &num_ch))
9507 {
9508 hddLog(VOS_TRACE_LEVEL_ERROR,
9509 "%s: failed to get valid channel list", __func__);
9510 return VOS_STATUS_E_FAILURE;
9511 }
9512 for (indx = 0; indx < num_ch; indx++)
9513 {
9514 if (channel == valid_ch[indx])
9515 {
9516 break;
9517 }
9518 }
9519
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309520 if (indx >= num_ch)
9521 {
9522 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9523 {
9524 eCsrBand band;
9525 unsigned int freq;
9526
9527 sme_GetFreqBand(hHal, &band);
9528
9529 if (eCSR_BAND_5G == band)
9530 {
9531#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9532 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9533 {
9534 freq = ieee80211_channel_to_frequency(channel,
9535 IEEE80211_BAND_2GHZ);
9536 }
9537 else
9538 {
9539 freq = ieee80211_channel_to_frequency(channel,
9540 IEEE80211_BAND_5GHZ);
9541 }
9542#else
9543 freq = ieee80211_channel_to_frequency(channel);
9544#endif
9545 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
9546 return VOS_STATUS_SUCCESS;
9547 }
9548 }
9549
9550 hddLog(VOS_TRACE_LEVEL_ERROR,
9551 "%s: Invalid Channel [%d]", __func__, channel);
9552 return VOS_STATUS_E_FAILURE;
9553 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009554 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309555
Jeff Johnson295189b2012-06-20 16:38:30 -07009556 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309557
Jeff Johnson295189b2012-06-20 16:38:30 -07009558}
9559
Viral Modi3a32cc52013-02-08 11:14:52 -08009560/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309561 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009562 * This function is used to set the channel number
9563 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309564static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009565 struct ieee80211_channel *chan,
9566 enum nl80211_channel_type channel_type
9567 )
9568{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309569 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009570 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009571 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009572 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309573 hdd_context_t *pHddCtx;
9574 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009575
9576 ENTER();
9577
9578 if( NULL == dev )
9579 {
9580 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009581 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009582 return -ENODEV;
9583 }
9584 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309585
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309586 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9587 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
9588 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08009589 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309590 "%s: device_mode = %s (%d) freq = %d", __func__,
9591 hdd_device_modetoString(pAdapter->device_mode),
9592 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309593
9594 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9595 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309596 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08009597 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309598 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009599 }
9600
9601 /*
9602 * Do freq to chan conversion
9603 * TODO: for 11a
9604 */
9605
9606 channel = ieee80211_frequency_to_channel(freq);
9607
9608 /* Check freq range */
9609 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9610 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9611 {
9612 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009613 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009614 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9615 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9616 return -EINVAL;
9617 }
9618
9619 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9620
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309621 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9622 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009623 {
9624 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
9625 {
9626 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009627 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009628 return -EINVAL;
9629 }
9630 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9631 "%s: set channel to [%d] for device mode =%d",
9632 __func__, channel,pAdapter->device_mode);
9633 }
9634 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009635 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009636 )
9637 {
9638 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9639 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9640 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9641
9642 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9643 {
9644 /* Link is up then return cant set channel*/
9645 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009646 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009647 return -EINVAL;
9648 }
9649
9650 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9651 pHddStaCtx->conn_info.operationChannel = channel;
9652 pRoamProfile->ChannelInfo.ChannelList =
9653 &pHddStaCtx->conn_info.operationChannel;
9654 }
9655 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009656 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009657 )
9658 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309659 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9660 {
9661 if(VOS_STATUS_SUCCESS !=
9662 wlan_hdd_validate_operation_channel(pAdapter,channel))
9663 {
9664 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009665 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309666 return -EINVAL;
9667 }
9668 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9669 }
9670 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009671 {
9672 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9673
9674 /* If auto channel selection is configured as enable/ 1 then ignore
9675 channel set by supplicant
9676 */
9677 if ( cfg_param->apAutoChannelSelection )
9678 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309679 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9680 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009681 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309682 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9683 __func__, hdd_device_modetoString(pAdapter->device_mode),
9684 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009685 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309686 else
9687 {
9688 if(VOS_STATUS_SUCCESS !=
9689 wlan_hdd_validate_operation_channel(pAdapter,channel))
9690 {
9691 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009692 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309693 return -EINVAL;
9694 }
9695 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9696 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009697 }
9698 }
9699 else
9700 {
9701 hddLog(VOS_TRACE_LEVEL_FATAL,
9702 "%s: Invalid device mode failed to set valid channel", __func__);
9703 return -EINVAL;
9704 }
9705 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309706 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009707}
9708
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309709static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9710 struct net_device *dev,
9711 struct ieee80211_channel *chan,
9712 enum nl80211_channel_type channel_type
9713 )
9714{
9715 int ret;
9716
9717 vos_ssr_protect(__func__);
9718 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9719 vos_ssr_unprotect(__func__);
9720
9721 return ret;
9722}
9723
Anurag Chouhan83026002016-12-13 22:46:21 +05309724#ifdef DHCP_SERVER_OFFLOAD
9725void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
9726 VOS_STATUS status)
9727{
9728 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
9729
9730 ENTER();
9731
9732 if (NULL == adapter)
9733 {
9734 hddLog(VOS_TRACE_LEVEL_ERROR,
9735 "%s: adapter is NULL",__func__);
9736 return;
9737 }
9738
9739 adapter->dhcp_status.dhcp_offload_status = status;
9740 vos_event_set(&adapter->dhcp_status.vos_event);
9741 return;
9742}
9743
9744/**
9745 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
9746 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309747 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +05309748 *
9749 * Return: None
9750 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309751VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
9752 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +05309753{
9754 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
9755 sir_dhcp_srv_offload_info dhcp_srv_info;
9756 tANI_U8 num_entries = 0;
9757 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
9758 tANI_U8 num;
9759 tANI_U32 temp;
9760 VOS_STATUS ret;
9761
9762 ENTER();
9763
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309764 if (!re_init) {
9765 ret = wlan_hdd_validate_context(hdd_ctx);
9766 if (0 != ret)
9767 return VOS_STATUS_E_INVAL;
9768 }
Anurag Chouhan83026002016-12-13 22:46:21 +05309769
9770 /* Prepare the request to send to SME */
9771 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
9772 if (NULL == dhcp_srv_info) {
9773 hddLog(VOS_TRACE_LEVEL_ERROR,
9774 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
9775 return VOS_STATUS_E_NOMEM;
9776 }
9777
9778 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
9779
9780 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
9781 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
9782 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
9783 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
9784 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
9785 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
9786
9787 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
9788 srv_ip,
9789 &num_entries,
Anurag Chouhanac145c22016-11-22 16:51:47 +05309790 IPADDR_NUM_ENTRIES, ".");
Anurag Chouhan83026002016-12-13 22:46:21 +05309791 if (num_entries != IPADDR_NUM_ENTRIES) {
9792 hddLog(VOS_TRACE_LEVEL_ERROR,
9793 "%s: incorrect IP address (%s) assigned for DHCP server!",
9794 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9795 vos_mem_free(dhcp_srv_info);
9796 return VOS_STATUS_E_FAILURE;
9797 }
9798
9799 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
9800 hddLog(VOS_TRACE_LEVEL_ERROR,
9801 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
9802 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9803 vos_mem_free(dhcp_srv_info);
9804 return VOS_STATUS_E_FAILURE;
9805 }
9806
9807 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
9808 hddLog(VOS_TRACE_LEVEL_ERROR,
9809 "%s: invalid IP address (%s)! The last field must be less than 100!",
9810 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9811 vos_mem_free(dhcp_srv_info);
9812 return VOS_STATUS_E_FAILURE;
9813 }
9814
9815 for (num = 0; num < num_entries; num++) {
9816 temp = srv_ip[num];
9817 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
9818 }
9819
9820 if (eHAL_STATUS_SUCCESS !=
9821 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
9822 hddLog(VOS_TRACE_LEVEL_ERROR,
9823 "%s: sme_set_dhcp_srv_offload fail!", __func__);
9824 vos_mem_free(dhcp_srv_info);
9825 return VOS_STATUS_E_FAILURE;
9826 }
9827
9828 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9829 "%s: enable DHCP Server offload successfully!", __func__);
9830
9831 vos_mem_free(dhcp_srv_info);
9832 return 0;
9833}
9834#endif /* DHCP_SERVER_OFFLOAD */
9835
Jeff Johnson295189b2012-06-20 16:38:30 -07009836#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9837static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9838 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009839#else
9840static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9841 struct cfg80211_beacon_data *params,
9842 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309843 enum nl80211_hidden_ssid hidden_ssid,
9844 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009845#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009846{
9847 tsap_Config_t *pConfig;
9848 beacon_data_t *pBeacon = NULL;
9849 struct ieee80211_mgmt *pMgmt_frame;
9850 v_U8_t *pIe=NULL;
9851 v_U16_t capab_info;
9852 eCsrAuthType RSNAuthType;
9853 eCsrEncryptionType RSNEncryptType;
9854 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309855 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009856 tpWLAN_SAPEventCB pSapEventCallback;
9857 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -07009858 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309859 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009860 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309861 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009862 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009863 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309864 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009865 v_BOOL_t MFPCapable = VOS_FALSE;
9866 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309867 v_BOOL_t sapEnable11AC =
9868 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +05309869 u_int16_t prev_rsn_length = 0;
9870
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 ENTER();
9872
Nitesh Shah9b066282017-06-06 18:05:52 +05309873 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309874 iniConfig = pHddCtx->cfg_ini;
9875
Jeff Johnson295189b2012-06-20 16:38:30 -07009876 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9877
9878 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9879
9880 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9881
9882 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9883
9884 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9885
9886 //channel is already set in the set_channel Call back
9887 //pConfig->channel = pCommitConfig->channel;
9888
9889 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309890 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009891 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9892
9893 pConfig->dtim_period = pBeacon->dtim_period;
9894
Arif Hussain6d2a3322013-11-17 19:50:10 -08009895 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009896 pConfig->dtim_period);
9897
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009898 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009899 {
9900 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009901 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309902 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9903 {
9904 tANI_BOOLEAN restartNeeded;
9905 pConfig->ieee80211d = 1;
9906 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9907 sme_setRegInfo(hHal, pConfig->countryCode);
9908 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9909 }
9910 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009911 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009912 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009913 pConfig->ieee80211d = 1;
9914 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9915 sme_setRegInfo(hHal, pConfig->countryCode);
9916 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009917 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009918 else
9919 {
9920 pConfig->ieee80211d = 0;
9921 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309922 /*
9923 * If auto channel is configured i.e. channel is 0,
9924 * so skip channel validation.
9925 */
9926 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9927 {
9928 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9929 {
9930 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009931 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309932 return -EINVAL;
9933 }
9934 }
9935 else
9936 {
9937 if(1 != pHddCtx->is_dynamic_channel_range_set)
9938 {
9939 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9940 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9941 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9942 }
9943 pHddCtx->is_dynamic_channel_range_set = 0;
9944 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009945 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009946 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009947 {
9948 pConfig->ieee80211d = 0;
9949 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309950
9951#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9952 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9953 pConfig->authType = eSAP_OPEN_SYSTEM;
9954 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9955 pConfig->authType = eSAP_SHARED_KEY;
9956 else
9957 pConfig->authType = eSAP_AUTO_SWITCH;
9958#else
9959 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9960 pConfig->authType = eSAP_OPEN_SYSTEM;
9961 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9962 pConfig->authType = eSAP_SHARED_KEY;
9963 else
9964 pConfig->authType = eSAP_AUTO_SWITCH;
9965#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009966
9967 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309968
9969 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009970 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +05309971#ifdef SAP_AUTH_OFFLOAD
9972 /* In case of sap offload, hostapd.conf is configuted with open mode and
9973 * security is configured from ini file. Due to open mode in hostapd.conf
9974 * privacy bit is set to false which will result in not sending,
9975 * data packets as encrypted.
9976 * If enable_sap_auth_offload is enabled in ini and
9977 * sap_auth_offload_sec_type is type of WPA2-PSK,
9978 * driver will set privacy bit to 1.
9979 */
9980 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
9981 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
9982 pConfig->privacy = VOS_TRUE;
9983#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009984
9985 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9986
9987 /*Set wps station to configured*/
9988 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9989
9990 if(pIe)
9991 {
9992 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9993 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009994 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009995 return -EINVAL;
9996 }
9997 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
9998 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009999 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070010000 /* Check 15 bit of WPS IE as it contain information for wps state
10001 * WPS state
10002 */
10003 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
10004 {
10005 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
10006 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
10007 {
10008 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
10009 }
10010 }
10011 }
10012 else
10013 {
10014 pConfig->wps_state = SAP_WPS_DISABLED;
10015 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010016 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070010017
c_hpothufe599e92014-06-16 11:38:55 +053010018 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10019 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10020 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
10021 eCSR_ENCRYPT_TYPE_NONE;
10022
Jeff Johnson295189b2012-06-20 16:38:30 -070010023 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053010024 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010025 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010026 WLAN_EID_RSN);
10027 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010028 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010029 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010030 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10031 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10032 pConfig->RSNWPAReqIELength);
10033 else
10034 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10035 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010036 /* The actual processing may eventually be more extensive than
10037 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070010038 * by the app.
10039 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010040 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010041 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10042 &RSNEncryptType,
10043 &mcRSNEncryptType,
10044 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010045 &MFPCapable,
10046 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010047 pConfig->RSNWPAReqIE[1]+2,
10048 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010049
10050 if( VOS_STATUS_SUCCESS == status )
10051 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010052 /* Now copy over all the security attributes you have
10053 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010054 * */
10055 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10056 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10057 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10058 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010059 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010060 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010061 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10062 }
10063 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010064
Jeff Johnson295189b2012-06-20 16:38:30 -070010065 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10066 pBeacon->tail, pBeacon->tail_len);
10067
10068 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
10069 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010070 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010071 {
10072 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053010073 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070010074 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010075 if (pConfig->RSNWPAReqIELength <=
10076 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
10077 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
10078 pIe[1] + 2);
10079 else
10080 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10081 pConfig->RSNWPAReqIELength);
10082
Jeff Johnson295189b2012-06-20 16:38:30 -070010083 }
10084 else
10085 {
10086 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010087 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10088 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10089 pConfig->RSNWPAReqIELength);
10090 else
10091 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10092 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010093 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010094 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10095 &RSNEncryptType,
10096 &mcRSNEncryptType,
10097 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010098 &MFPCapable,
10099 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010100 pConfig->RSNWPAReqIE[1]+2,
10101 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010102
10103 if( VOS_STATUS_SUCCESS == status )
10104 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010105 /* Now copy over all the security attributes you have
10106 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010107 * */
10108 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10109 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10110 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10111 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010112 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010113 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010114 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10115 }
10116 }
10117 }
10118
Kapil Gupta137ef892016-12-13 19:38:00 +053010119 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070010120 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
10121 return -EINVAL;
10122 }
10123
Jeff Johnson295189b2012-06-20 16:38:30 -070010124 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
10125
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010126#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010127 if (params->ssid != NULL)
10128 {
10129 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
10130 pConfig->SSIDinfo.ssid.length = params->ssid_len;
10131 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10132 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10133 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010134#else
10135 if (ssid != NULL)
10136 {
10137 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
10138 pConfig->SSIDinfo.ssid.length = ssid_len;
10139 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10140 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10141 }
10142#endif
10143
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010144 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070010145 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010146
Jeff Johnson295189b2012-06-20 16:38:30 -070010147 /* default value */
10148 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
10149 pConfig->num_accept_mac = 0;
10150 pConfig->num_deny_mac = 0;
10151
10152 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10153 pBeacon->tail, pBeacon->tail_len);
10154
10155 /* pIe for black list is following form:
10156 type : 1 byte
10157 length : 1 byte
10158 OUI : 4 bytes
10159 acl type : 1 byte
10160 no of mac addr in black list: 1 byte
10161 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010162 */
10163 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010164 {
10165 pConfig->SapMacaddr_acl = pIe[6];
10166 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010167 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010168 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010169 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
10170 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010171 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10172 for (i = 0; i < pConfig->num_deny_mac; i++)
10173 {
10174 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10175 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010176 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010177 }
10178 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10179 pBeacon->tail, pBeacon->tail_len);
10180
10181 /* pIe for white list is following form:
10182 type : 1 byte
10183 length : 1 byte
10184 OUI : 4 bytes
10185 acl type : 1 byte
10186 no of mac addr in white list: 1 byte
10187 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010188 */
10189 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010190 {
10191 pConfig->SapMacaddr_acl = pIe[6];
10192 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010193 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010194 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010195 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
10196 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010197 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10198 for (i = 0; i < pConfig->num_accept_mac; i++)
10199 {
10200 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10201 acl_entry++;
10202 }
10203 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010204
Jeff Johnson295189b2012-06-20 16:38:30 -070010205 wlan_hdd_set_sapHwmode(pHostapdAdapter);
10206
Jeff Johnsone7245742012-09-05 17:12:55 -070010207#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010208 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010209 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
10210 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053010211 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
10212 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010213 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
10214 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010215 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
10216 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070010217 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010218 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070010219 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010220 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010221
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010222 /* If ACS disable and selected channel <= 14
10223 * OR
10224 * ACS enabled and ACS operating band is choosen as 2.4
10225 * AND
10226 * VHT in 2.4G Disabled
10227 * THEN
10228 * Fallback to 11N mode
10229 */
10230 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
10231 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053010232 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010233 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010234 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010235 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
10236 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010237 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
10238 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010239 }
10240#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010241
Jeff Johnson295189b2012-06-20 16:38:30 -070010242 // ht_capab is not what the name conveys,this is used for protection bitmap
10243 pConfig->ht_capab =
10244 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
10245
Kapil Gupta137ef892016-12-13 19:38:00 +053010246 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010247 {
10248 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10249 return -EINVAL;
10250 }
10251
10252 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010253 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070010254 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
10255 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010256 pConfig->obssProtEnabled =
10257 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070010258
Chet Lanctot8cecea22014-02-11 19:09:36 -080010259#ifdef WLAN_FEATURE_11W
10260 pConfig->mfpCapable = MFPCapable;
10261 pConfig->mfpRequired = MFPRequired;
10262 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
10263 pConfig->mfpCapable, pConfig->mfpRequired);
10264#endif
10265
Arif Hussain6d2a3322013-11-17 19:50:10 -080010266 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070010267 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010268 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
10269 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
10270 (int)pConfig->channel);
10271 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
10272 pConfig->SapHw_mode, pConfig->privacy,
10273 pConfig->authType);
10274 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
10275 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
10276 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
10277 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070010278
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010279 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010280 {
10281 //Bss already started. just return.
10282 //TODO Probably it should update some beacon params.
10283 hddLog( LOGE, "Bss Already started...Ignore the request");
10284 EXIT();
10285 return 0;
10286 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010287
Agarwal Ashish51325b52014-06-16 16:50:49 +053010288 if (vos_max_concurrent_connections_reached()) {
10289 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10290 return -EINVAL;
10291 }
10292
Jeff Johnson295189b2012-06-20 16:38:30 -070010293 pConfig->persona = pHostapdAdapter->device_mode;
10294
Peng Xu2446a892014-09-05 17:21:18 +053010295 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
10296 if ( NULL != psmeConfig)
10297 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010298 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053010299 sme_GetConfigParam(hHal, psmeConfig);
10300 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010301#ifdef WLAN_FEATURE_AP_HT40_24G
10302 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
10303 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
10304 && pHddCtx->cfg_ini->apHT40_24GEnabled)
10305 {
10306 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
10307 sme_UpdateConfig (hHal, psmeConfig);
10308 }
10309#endif
Peng Xu2446a892014-09-05 17:21:18 +053010310 vos_mem_free(psmeConfig);
10311 }
Peng Xuafc34e32014-09-25 13:23:55 +053010312 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053010313
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010314 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10315
Jeff Johnson295189b2012-06-20 16:38:30 -070010316 pSapEventCallback = hdd_hostapd_SAPEventCB;
10317 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
10318 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
10319 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010320 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010321 ret = -EINVAL;
10322 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070010323 }
10324
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010325 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070010326 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
10327
10328 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010329
Jeff Johnson295189b2012-06-20 16:38:30 -070010330 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010331 {
10332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010333 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070010334 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010335 VOS_ASSERT(0);
10336 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010337
Jeff Johnson295189b2012-06-20 16:38:30 -070010338 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053010339 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
10340 VOS_STATUS_SUCCESS)
10341 {
10342 hddLog(LOGE,FL("Fail to get Softap sessionID"));
10343 VOS_ASSERT(0);
10344 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053010345 /* Initialize WMM configuation */
10346 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010347 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010348
Anurag Chouhan83026002016-12-13 22:46:21 +053010349#ifdef DHCP_SERVER_OFFLOAD
10350 /* set dhcp server offload */
10351 if (iniConfig->enable_dhcp_srv_offload &&
10352 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010353 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010354 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010355 if (!VOS_IS_STATUS_SUCCESS(status))
10356 {
10357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10358 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010359 vos_event_reset(&pHostapdState->vosEvent);
10360 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10361 status = vos_wait_single_event(&pHostapdState->vosEvent,
10362 10000);
10363 if (!VOS_IS_STATUS_SUCCESS(status)) {
10364 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010365 ret = -EINVAL;
10366 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010367 }
10368 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010369 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010370 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
10371 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
10372 {
10373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10374 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
10375 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010376 vos_event_reset(&pHostapdState->vosEvent);
10377 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10378 status = vos_wait_single_event(&pHostapdState->vosEvent,
10379 10000);
10380 if (!VOS_IS_STATUS_SUCCESS(status)) {
10381 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010382 ret = -EINVAL;
10383 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010384 }
10385 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010386 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010387#ifdef MDNS_OFFLOAD
10388 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010389 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010390 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
10391 if (VOS_IS_STATUS_SUCCESS(status))
10392 {
10393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10394 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010395 vos_event_reset(&pHostapdState->vosEvent);
10396 if (VOS_STATUS_SUCCESS ==
10397 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10398 status = vos_wait_single_event(&pHostapdState->vosEvent,
10399 10000);
10400 if (!VOS_IS_STATUS_SUCCESS(status)) {
10401 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010402 ret = -EINVAL;
10403 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010404 }
10405 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010406 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010407 status = vos_wait_single_event(&pHostapdAdapter->
10408 mdns_status.vos_event, 2000);
10409 if (!VOS_IS_STATUS_SUCCESS(status) ||
10410 pHostapdAdapter->mdns_status.mdns_enable_status ||
10411 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
10412 pHostapdAdapter->mdns_status.mdns_resp_status)
10413 {
10414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10415 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
10416 pHostapdAdapter->mdns_status.mdns_enable_status,
10417 pHostapdAdapter->mdns_status.mdns_fqdn_status,
10418 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010419 vos_event_reset(&pHostapdState->vosEvent);
10420 if (VOS_STATUS_SUCCESS ==
10421 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10422 status = vos_wait_single_event(&pHostapdState->vosEvent,
10423 10000);
10424 if (!VOS_IS_STATUS_SUCCESS(status)) {
10425 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010426 ret = -EINVAL;
10427 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010428 }
10429 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010430 }
10431 }
10432#endif /* MDNS_OFFLOAD */
10433 } else {
10434 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10435 ("DHCP Disabled ini %d, FW %d"),
10436 iniConfig->enable_dhcp_srv_offload,
10437 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053010438 }
10439#endif /* DHCP_SERVER_OFFLOAD */
10440
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010441#ifdef WLAN_FEATURE_P2P_DEBUG
10442 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
10443 {
10444 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
10445 {
10446 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10447 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010448 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010449 }
10450 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
10451 {
10452 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10453 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010454 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010455 }
10456 }
10457#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053010458 /* Check and restart SAP if it is on Unsafe channel */
10459 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010460
Jeff Johnson295189b2012-06-20 16:38:30 -070010461 pHostapdState->bCommit = TRUE;
10462 EXIT();
10463
10464 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010465error:
10466 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10467 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010468}
10469
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010470#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010471static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010472 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070010473 struct beacon_parameters *params)
10474{
10475 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010476 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010477 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010478
10479 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010480
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010481 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10482 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
10483 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010484 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
10485 hdd_device_modetoString(pAdapter->device_mode),
10486 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010487
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010488 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10489 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010490 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010491 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010492 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010493 }
10494
Agarwal Ashish51325b52014-06-16 16:50:49 +053010495 if (vos_max_concurrent_connections_reached()) {
10496 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10497 return -EINVAL;
10498 }
10499
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010500 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010501 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010502 )
10503 {
10504 beacon_data_t *old,*new;
10505
10506 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010507
Jeff Johnson295189b2012-06-20 16:38:30 -070010508 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010509 {
10510 hddLog(VOS_TRACE_LEVEL_WARN,
10511 FL("already beacon info added to session(%d)"),
10512 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010513 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010514 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010515
10516 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10517
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010518 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070010519 {
10520 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010521 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010522 return -EINVAL;
10523 }
10524
10525 pAdapter->sessionCtx.ap.beacon = new;
10526
10527 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10528 }
10529
10530 EXIT();
10531 return status;
10532}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010533
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010534static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
10535 struct net_device *dev,
10536 struct beacon_parameters *params)
10537{
10538 int ret;
10539
10540 vos_ssr_protect(__func__);
10541 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
10542 vos_ssr_unprotect(__func__);
10543
10544 return ret;
10545}
10546
10547static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010548 struct net_device *dev,
10549 struct beacon_parameters *params)
10550{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010551 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010552 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10553 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010554 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010555
10556 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010557
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010558 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10559 TRACE_CODE_HDD_CFG80211_SET_BEACON,
10560 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
10561 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10562 __func__, hdd_device_modetoString(pAdapter->device_mode),
10563 pAdapter->device_mode);
10564
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010565 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10566 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010567 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010568 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010569 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010570 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010571
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010572 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010573 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010574 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010575 {
10576 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010577
Jeff Johnson295189b2012-06-20 16:38:30 -070010578 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010579
Jeff Johnson295189b2012-06-20 16:38:30 -070010580 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010581 {
10582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10583 FL("session(%d) old and new heads points to NULL"),
10584 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010585 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010586 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010587
10588 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10589
10590 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010591 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010592 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010593 return -EINVAL;
10594 }
10595
10596 pAdapter->sessionCtx.ap.beacon = new;
10597
10598 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10599 }
10600
10601 EXIT();
10602 return status;
10603}
10604
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010605static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
10606 struct net_device *dev,
10607 struct beacon_parameters *params)
10608{
10609 int ret;
10610
10611 vos_ssr_protect(__func__);
10612 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
10613 vos_ssr_unprotect(__func__);
10614
10615 return ret;
10616}
10617
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010618#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10619
10620#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010621static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010622 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010623#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010624static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010625 struct net_device *dev)
10626#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010627{
10628 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070010629 hdd_context_t *pHddCtx = NULL;
10630 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010631 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010632 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010633
10634 ENTER();
10635
10636 if (NULL == pAdapter)
10637 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010639 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010640 return -ENODEV;
10641 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010642
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010643 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10644 TRACE_CODE_HDD_CFG80211_STOP_AP,
10645 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010646 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10647 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010648 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010649 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010650 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070010651 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010652
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010653 pScanInfo = &pHddCtx->scan_info;
10654
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010655 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10656 __func__, hdd_device_modetoString(pAdapter->device_mode),
10657 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010658
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010659 ret = wlan_hdd_scan_abort(pAdapter);
10660
Girish Gowli4bf7a632014-06-12 13:42:11 +053010661 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070010662 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010663 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10664 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010665
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010666 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070010667 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10669 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080010670
Jeff Johnsone7245742012-09-05 17:12:55 -070010671 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010672 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070010673 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010674 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010675 }
10676
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010677 /* Delete all associated STAs before stopping AP/P2P GO */
10678 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053010679 hdd_hostapd_stop(dev);
10680
Jeff Johnson295189b2012-06-20 16:38:30 -070010681 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010682 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010683 )
10684 {
10685 beacon_data_t *old;
10686
10687 old = pAdapter->sessionCtx.ap.beacon;
10688
10689 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010690 {
10691 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10692 FL("session(%d) beacon data points to NULL"),
10693 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010694 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010695 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010696
Jeff Johnson295189b2012-06-20 16:38:30 -070010697 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010698
10699 mutex_lock(&pHddCtx->sap_lock);
10700 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10701 {
Jeff Johnson4416a782013-03-25 14:17:50 -070010702 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010703 {
10704 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10705
10706 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10707
10708 if (!VOS_IS_STATUS_SUCCESS(status))
10709 {
10710 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010711 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010712 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010713 }
10714 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010715 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010716 /* BSS stopped, clear the active sessions for this device mode */
10717 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010718 }
10719 mutex_unlock(&pHddCtx->sap_lock);
10720
10721 if(status != VOS_STATUS_SUCCESS)
10722 {
10723 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010724 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010725 return -EINVAL;
10726 }
10727
Jeff Johnson4416a782013-03-25 14:17:50 -070010728 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010729 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
10730 ==eHAL_STATUS_FAILURE)
10731 {
10732 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010733 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010734 }
10735
Jeff Johnson4416a782013-03-25 14:17:50 -070010736 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010737 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10738 eANI_BOOLEAN_FALSE) )
10739 {
10740 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010741 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010742 }
10743
10744 // Reset WNI_CFG_PROBE_RSP Flags
10745 wlan_hdd_reset_prob_rspies(pAdapter);
10746
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010747 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
10748
Jeff Johnson295189b2012-06-20 16:38:30 -070010749 pAdapter->sessionCtx.ap.beacon = NULL;
10750 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010751#ifdef WLAN_FEATURE_P2P_DEBUG
10752 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
10753 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
10754 {
10755 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
10756 "GO got removed");
10757 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
10758 }
10759#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010760 }
10761 EXIT();
10762 return status;
10763}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010764
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010765#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10766static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
10767 struct net_device *dev)
10768{
10769 int ret;
10770
10771 vos_ssr_protect(__func__);
10772 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
10773 vos_ssr_unprotect(__func__);
10774
10775 return ret;
10776}
10777#else
10778static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
10779 struct net_device *dev)
10780{
10781 int ret;
10782
10783 vos_ssr_protect(__func__);
10784 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
10785 vos_ssr_unprotect(__func__);
10786
10787 return ret;
10788}
10789#endif
10790
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010791#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
10792
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010793static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010794 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010795 struct cfg80211_ap_settings *params)
10796{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010797 hdd_adapter_t *pAdapter;
10798 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010799 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010800
10801 ENTER();
10802
Girish Gowlib143d7a2015-02-18 19:39:55 +053010803 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010804 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010805 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053010806 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010807 return -ENODEV;
10808 }
10809
10810 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10811 if (NULL == pAdapter)
10812 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010814 "%s: HDD adapter is Null", __func__);
10815 return -ENODEV;
10816 }
10817
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010818 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10819 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
10820 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010821 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
10822 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010823 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010824 "%s: HDD adapter magic is invalid", __func__);
10825 return -ENODEV;
10826 }
10827
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010828 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
10829
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010830 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010831 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010832 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010833 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010834 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010835 }
10836
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010837 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
10838 __func__, hdd_device_modetoString(pAdapter->device_mode),
10839 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010840
10841 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010842 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010843 )
10844 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010845 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010846
10847 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010848
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010849 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010850 {
10851 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10852 FL("already beacon info added to session(%d)"),
10853 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010854 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010855 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010856
Girish Gowlib143d7a2015-02-18 19:39:55 +053010857#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10858 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10859 &new,
10860 &params->beacon);
10861#else
10862 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10863 &new,
10864 &params->beacon,
10865 params->dtim_period);
10866#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010867
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010868 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010869 {
10870 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010871 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010872 return -EINVAL;
10873 }
10874 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010875#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010876 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10877#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10878 params->channel, params->channel_type);
10879#else
10880 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10881#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010882#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010883 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010884 params->ssid_len, params->hidden_ssid,
10885 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010886 }
10887
10888 EXIT();
10889 return status;
10890}
10891
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010892static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10893 struct net_device *dev,
10894 struct cfg80211_ap_settings *params)
10895{
10896 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010897
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010898 vos_ssr_protect(__func__);
10899 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10900 vos_ssr_unprotect(__func__);
10901
10902 return ret;
10903}
10904
10905static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010906 struct net_device *dev,
10907 struct cfg80211_beacon_data *params)
10908{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010909 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010910 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010911 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010912
10913 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010914
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010915 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10916 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10917 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010918 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010919 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010920
10921 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10922 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010923 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010924 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010925 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010926 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010927
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010928 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010929 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010930 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010931 {
10932 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010933
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010934 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010935
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010936 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010937 {
10938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10939 FL("session(%d) beacon data points to NULL"),
10940 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010941 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010942 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010943
10944 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10945
10946 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010947 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010948 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010949 return -EINVAL;
10950 }
10951
10952 pAdapter->sessionCtx.ap.beacon = new;
10953
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010954 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10955 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010956 }
10957
10958 EXIT();
10959 return status;
10960}
10961
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010962static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10963 struct net_device *dev,
10964 struct cfg80211_beacon_data *params)
10965{
10966 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010967
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010968 vos_ssr_protect(__func__);
10969 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10970 vos_ssr_unprotect(__func__);
10971
10972 return ret;
10973}
10974
10975#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010976
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010977static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010978 struct net_device *dev,
10979 struct bss_parameters *params)
10980{
10981 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010982 hdd_context_t *pHddCtx;
10983 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010984
10985 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010986
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010987 if (NULL == pAdapter)
10988 {
10989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10990 "%s: HDD adapter is Null", __func__);
10991 return -ENODEV;
10992 }
10993 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010994 ret = wlan_hdd_validate_context(pHddCtx);
10995 if (0 != ret)
10996 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010997 return ret;
10998 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010999 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11000 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
11001 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011002 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11003 __func__, hdd_device_modetoString(pAdapter->device_mode),
11004 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011005
11006 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011007 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011008 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011009 {
11010 /* ap_isolate == -1 means that in change bss, upper layer doesn't
11011 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011012 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070011013 {
11014 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011015 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011016 }
11017
11018 EXIT();
11019 return 0;
11020}
11021
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011022static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
11023 struct net_device *dev,
11024 struct bss_parameters *params)
11025{
11026 int ret;
11027
11028 vos_ssr_protect(__func__);
11029 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
11030 vos_ssr_unprotect(__func__);
11031
11032 return ret;
11033}
Kiet Lam10841362013-11-01 11:36:50 +053011034/* FUNCTION: wlan_hdd_change_country_code_cd
11035* to wait for contry code completion
11036*/
11037void* wlan_hdd_change_country_code_cb(void *pAdapter)
11038{
11039 hdd_adapter_t *call_back_pAdapter = pAdapter;
11040 complete(&call_back_pAdapter->change_country_code);
11041 return NULL;
11042}
11043
Jeff Johnson295189b2012-06-20 16:38:30 -070011044/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011045 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070011046 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
11047 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011048int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011049 struct net_device *ndev,
11050 enum nl80211_iftype type,
11051 u32 *flags,
11052 struct vif_params *params
11053 )
11054{
11055 struct wireless_dev *wdev;
11056 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011057 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070011058 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011059 tCsrRoamProfile *pRoamProfile = NULL;
11060 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011061 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011062 eMib_dot11DesiredBssType connectedBssType;
11063 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011064 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011065
11066 ENTER();
11067
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011068 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011069 {
11070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11071 "%s: Adapter context is null", __func__);
11072 return VOS_STATUS_E_FAILURE;
11073 }
11074
11075 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11076 if (!pHddCtx)
11077 {
11078 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11079 "%s: HDD context is null", __func__);
11080 return VOS_STATUS_E_FAILURE;
11081 }
11082
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011083 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11084 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
11085 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011086 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011087 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011088 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011089 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011090 }
11091
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011092 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11093 __func__, hdd_device_modetoString(pAdapter->device_mode),
11094 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011095
Agarwal Ashish51325b52014-06-16 16:50:49 +053011096 if (vos_max_concurrent_connections_reached()) {
11097 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11098 return -EINVAL;
11099 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011100 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011101 wdev = ndev->ieee80211_ptr;
11102
11103#ifdef WLAN_BTAMP_FEATURE
11104 if((NL80211_IFTYPE_P2P_CLIENT == type)||
11105 (NL80211_IFTYPE_ADHOC == type)||
11106 (NL80211_IFTYPE_AP == type)||
11107 (NL80211_IFTYPE_P2P_GO == type))
11108 {
11109 pHddCtx->isAmpAllowed = VOS_FALSE;
11110 // stop AMP traffic
11111 status = WLANBAP_StopAmp();
11112 if(VOS_STATUS_SUCCESS != status )
11113 {
11114 pHddCtx->isAmpAllowed = VOS_TRUE;
11115 hddLog(VOS_TRACE_LEVEL_FATAL,
11116 "%s: Failed to stop AMP", __func__);
11117 return -EINVAL;
11118 }
11119 }
11120#endif //WLAN_BTAMP_FEATURE
11121 /* Reset the current device mode bit mask*/
11122 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
11123
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053011124 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
11125 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
11126 (type == NL80211_IFTYPE_P2P_GO)))
11127 {
11128 /* Notify Mode change in case of concurrency.
11129 * Below function invokes TDLS teardown Functionality Since TDLS is
11130 * not Supported in case of concurrency i.e Once P2P session
11131 * is detected disable offchannel and teardown TDLS links
11132 */
11133 hddLog(LOG1,
11134 FL("Device mode = %d Interface type = %d"),
11135 pAdapter->device_mode, type);
11136 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
11137 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053011138
Jeff Johnson295189b2012-06-20 16:38:30 -070011139 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011140 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070011141 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011142 )
11143 {
11144 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011145 if (!pWextState)
11146 {
11147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11148 "%s: pWextState is null", __func__);
11149 return VOS_STATUS_E_FAILURE;
11150 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011151 pRoamProfile = &pWextState->roamProfile;
11152 LastBSSType = pRoamProfile->BSSType;
11153
11154 switch (type)
11155 {
11156 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011157 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011158 hddLog(VOS_TRACE_LEVEL_INFO,
11159 "%s: setting interface Type to INFRASTRUCTURE", __func__);
11160 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011161#ifdef WLAN_FEATURE_11AC
11162 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
11163 {
11164 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
11165 }
11166#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011167 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070011168 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011169 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011170 //Check for sub-string p2p to confirm its a p2p interface
11171 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011172 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053011173#ifdef FEATURE_WLAN_TDLS
11174 mutex_lock(&pHddCtx->tdls_lock);
11175 wlan_hdd_tdls_exit(pAdapter, TRUE);
11176 mutex_unlock(&pHddCtx->tdls_lock);
11177#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011178 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11179 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11180 }
11181 else
11182 {
11183 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011184 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011185 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011186 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053011187
Jeff Johnson295189b2012-06-20 16:38:30 -070011188 case NL80211_IFTYPE_ADHOC:
11189 hddLog(VOS_TRACE_LEVEL_INFO,
11190 "%s: setting interface Type to ADHOC", __func__);
11191 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
11192 pRoamProfile->phyMode =
11193 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070011194 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011195 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053011196 hdd_set_ibss_ops( pAdapter );
11197 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053011198
11199 status = hdd_sta_id_hash_attach(pAdapter);
11200 if (VOS_STATUS_SUCCESS != status) {
11201 hddLog(VOS_TRACE_LEVEL_ERROR,
11202 FL("Failed to initialize hash for IBSS"));
11203 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011204 break;
11205
11206 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011207 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011208 {
11209 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11210 "%s: setting interface Type to %s", __func__,
11211 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
11212
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011213 //Cancel any remain on channel for GO mode
11214 if (NL80211_IFTYPE_P2P_GO == type)
11215 {
11216 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
11217 }
Mohit Khanna0f232092012-09-11 14:46:08 -070011218 if (NL80211_IFTYPE_AP == type)
11219 {
11220 /* As Loading WLAN Driver one interface being created for p2p device
11221 * address. This will take one HW STA and the max number of clients
11222 * that can connect to softAP will be reduced by one. so while changing
11223 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
11224 * interface as it is not required in SoftAP mode.
11225 */
11226
11227 // Get P2P Adapter
11228 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
11229
11230 if (pP2pAdapter)
11231 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053011232 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053011233 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070011234 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
11235 }
11236 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053011237 //Disable IMPS & BMPS for SAP/GO
11238 if(VOS_STATUS_E_FAILURE ==
11239 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
11240 {
11241 //Fail to Exit BMPS
11242 VOS_ASSERT(0);
11243 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053011244
11245 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
11246
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011247#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070011248
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011249 /* A Mutex Lock is introduced while changing the mode to
11250 * protect the concurrent access for the Adapters by TDLS
11251 * module.
11252 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011253 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011254#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011255 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053011256 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011257 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070011258 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11259 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011260#ifdef FEATURE_WLAN_TDLS
11261 mutex_unlock(&pHddCtx->tdls_lock);
11262#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011263 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
11264 (pConfig->apRandomBssidEnabled))
11265 {
11266 /* To meet Android requirements create a randomized
11267 MAC address of the form 02:1A:11:Fx:xx:xx */
11268 get_random_bytes(&ndev->dev_addr[3], 3);
11269 ndev->dev_addr[0] = 0x02;
11270 ndev->dev_addr[1] = 0x1A;
11271 ndev->dev_addr[2] = 0x11;
11272 ndev->dev_addr[3] |= 0xF0;
11273 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
11274 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080011275 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
11276 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011277 }
11278
Jeff Johnson295189b2012-06-20 16:38:30 -070011279 hdd_set_ap_ops( pAdapter->dev );
11280
Kiet Lam10841362013-11-01 11:36:50 +053011281 /* This is for only SAP mode where users can
11282 * control country through ini.
11283 * P2P GO follows station country code
11284 * acquired during the STA scanning. */
11285 if((NL80211_IFTYPE_AP == type) &&
11286 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
11287 {
11288 int status = 0;
11289 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
11290 "%s: setting country code from INI ", __func__);
11291 init_completion(&pAdapter->change_country_code);
11292 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
11293 (void *)(tSmeChangeCountryCallback)
11294 wlan_hdd_change_country_code_cb,
11295 pConfig->apCntryCode, pAdapter,
11296 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053011297 eSIR_FALSE,
11298 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053011299 if (eHAL_STATUS_SUCCESS == status)
11300 {
11301 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011302 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053011303 &pAdapter->change_country_code,
11304 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011305 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053011306 {
11307 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011308 FL("SME Timed out while setting country code %ld"),
11309 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080011310
11311 if (pHddCtx->isLogpInProgress)
11312 {
11313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11314 "%s: LOGP in Progress. Ignore!!!", __func__);
11315 return -EAGAIN;
11316 }
Kiet Lam10841362013-11-01 11:36:50 +053011317 }
11318 }
11319 else
11320 {
11321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011322 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053011323 return -EINVAL;
11324 }
11325 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011326 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070011327 if(status != VOS_STATUS_SUCCESS)
11328 {
11329 hddLog(VOS_TRACE_LEVEL_FATAL,
11330 "%s: Error initializing the ap mode", __func__);
11331 return -EINVAL;
11332 }
11333 hdd_set_conparam(1);
11334
Nirav Shah7e3c8132015-06-22 23:51:42 +053011335 status = hdd_sta_id_hash_attach(pAdapter);
11336 if (VOS_STATUS_SUCCESS != status)
11337 {
11338 hddLog(VOS_TRACE_LEVEL_ERROR,
11339 FL("Failed to initialize hash for AP"));
11340 return -EINVAL;
11341 }
11342
Jeff Johnson295189b2012-06-20 16:38:30 -070011343 /*interface type changed update in wiphy structure*/
11344 if(wdev)
11345 {
11346 wdev->iftype = type;
11347 pHddCtx->change_iface = type;
11348 }
11349 else
11350 {
11351 hddLog(VOS_TRACE_LEVEL_ERROR,
11352 "%s: ERROR !!!! Wireless dev is NULL", __func__);
11353 return -EINVAL;
11354 }
11355 goto done;
11356 }
11357
11358 default:
11359 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11360 __func__);
11361 return -EOPNOTSUPP;
11362 }
11363 }
11364 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011365 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011366 )
11367 {
11368 switch(type)
11369 {
11370 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011371 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011372 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053011373
11374 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011375#ifdef FEATURE_WLAN_TDLS
11376
11377 /* A Mutex Lock is introduced while changing the mode to
11378 * protect the concurrent access for the Adapters by TDLS
11379 * module.
11380 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011381 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011382#endif
c_hpothu002231a2015-02-05 14:58:51 +053011383 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011384 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011385 //Check for sub-string p2p to confirm its a p2p interface
11386 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011387 {
11388 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11389 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11390 }
11391 else
11392 {
11393 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011394 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011395 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053011396
11397 /* set con_mode to STA only when no SAP concurrency mode */
11398 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
11399 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070011400 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011401 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
11402 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011403#ifdef FEATURE_WLAN_TDLS
11404 mutex_unlock(&pHddCtx->tdls_lock);
11405#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053011406 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070011407 if( VOS_STATUS_SUCCESS != status )
11408 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070011409 /* In case of JB, for P2P-GO, only change interface will be called,
11410 * This is the right place to enable back bmps_imps()
11411 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011412 if (pHddCtx->hdd_wlan_suspended)
11413 {
11414 hdd_set_pwrparams(pHddCtx);
11415 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011416 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011417 goto done;
11418 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011419 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011420 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011421 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11422 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011423 goto done;
11424 default:
11425 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11426 __func__);
11427 return -EOPNOTSUPP;
11428
11429 }
11430
11431 }
11432 else
11433 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011434 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
11435 __func__, hdd_device_modetoString(pAdapter->device_mode),
11436 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011437 return -EOPNOTSUPP;
11438 }
11439
11440
11441 if(pRoamProfile)
11442 {
11443 if ( LastBSSType != pRoamProfile->BSSType )
11444 {
11445 /*interface type changed update in wiphy structure*/
11446 wdev->iftype = type;
11447
11448 /*the BSS mode changed, We need to issue disconnect
11449 if connected or in IBSS disconnect state*/
11450 if ( hdd_connGetConnectedBssType(
11451 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
11452 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
11453 {
11454 /*need to issue a disconnect to CSR.*/
11455 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11456 if( eHAL_STATUS_SUCCESS ==
11457 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11458 pAdapter->sessionId,
11459 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11460 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011461 ret = wait_for_completion_interruptible_timeout(
11462 &pAdapter->disconnect_comp_var,
11463 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11464 if (ret <= 0)
11465 {
11466 hddLog(VOS_TRACE_LEVEL_ERROR,
11467 FL("wait on disconnect_comp_var failed %ld"), ret);
11468 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011469 }
11470 }
11471 }
11472 }
11473
11474done:
11475 /*set bitmask based on updated value*/
11476 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070011477
11478 /* Only STA mode support TM now
11479 * all other mode, TM feature should be disabled */
11480 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
11481 (~VOS_STA & pHddCtx->concurrency_mode) )
11482 {
11483 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
11484 }
11485
Jeff Johnson295189b2012-06-20 16:38:30 -070011486#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011487 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011488 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070011489 {
11490 //we are ok to do AMP
11491 pHddCtx->isAmpAllowed = VOS_TRUE;
11492 }
11493#endif //WLAN_BTAMP_FEATURE
11494 EXIT();
11495 return 0;
11496}
11497
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011498/*
11499 * FUNCTION: wlan_hdd_cfg80211_change_iface
11500 * wrapper function to protect the actual implementation from SSR.
11501 */
11502int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
11503 struct net_device *ndev,
11504 enum nl80211_iftype type,
11505 u32 *flags,
11506 struct vif_params *params
11507 )
11508{
11509 int ret;
11510
11511 vos_ssr_protect(__func__);
11512 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
11513 vos_ssr_unprotect(__func__);
11514
11515 return ret;
11516}
11517
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011518#ifdef FEATURE_WLAN_TDLS
11519static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011520 struct net_device *dev,
11521#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11522 const u8 *mac,
11523#else
11524 u8 *mac,
11525#endif
11526 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011527{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011528 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011529 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011530 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011531 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011532 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011533 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011534
11535 ENTER();
11536
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011537 if (!dev) {
11538 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
11539 return -EINVAL;
11540 }
11541
11542 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11543 if (!pAdapter) {
11544 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
11545 return -EINVAL;
11546 }
11547
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011548 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011549 {
11550 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11551 "Invalid arguments");
11552 return -EINVAL;
11553 }
Hoonki Lee27511902013-03-14 18:19:06 -070011554
11555 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
11556 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
11557 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070011559 "%s: TDLS mode is disabled OR not enabled in FW."
11560 MAC_ADDRESS_STR " Request declined.",
11561 __func__, MAC_ADDR_ARRAY(mac));
11562 return -ENOTSUPP;
11563 }
11564
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011565 if (pHddCtx->isLogpInProgress)
11566 {
11567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11568 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053011569 wlan_hdd_tdls_set_link_status(pAdapter,
11570 mac,
11571 eTDLS_LINK_IDLE,
11572 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011573 return -EBUSY;
11574 }
11575
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011576 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053011577 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011578
11579 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011580 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011581 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
11582 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011583 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011584 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011585 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011586
11587 /* in add station, we accept existing valid staId if there is */
11588 if ((0 == update) &&
11589 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
11590 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011591 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011593 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011594 " link_status %d. staId %d. add station ignored.",
11595 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011596 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011597 return 0;
11598 }
11599 /* in change station, we accept only when staId is valid */
11600 if ((1 == update) &&
11601 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
11602 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
11603 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011604 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011606 "%s: " MAC_ADDRESS_STR
11607 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011608 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
11609 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
11610 mutex_unlock(&pHddCtx->tdls_lock);
11611 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011612 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011613 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011614
11615 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053011616 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011617 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11619 "%s: " MAC_ADDRESS_STR
11620 " TDLS setup is ongoing. Request declined.",
11621 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070011622 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011623 }
11624
11625 /* first to check if we reached to maximum supported TDLS peer.
11626 TODO: for now, return -EPERM looks working fine,
11627 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011628 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
11629 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011630 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11632 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011633 " TDLS Max peer already connected. Request declined."
11634 " Num of peers (%d), Max allowed (%d).",
11635 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
11636 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011637 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011638 }
11639 else
11640 {
11641 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011642 mutex_lock(&pHddCtx->tdls_lock);
11643 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011644 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011645 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011646 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11648 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
11649 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011650 return -EPERM;
11651 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011652 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011653 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011654 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053011655 wlan_hdd_tdls_set_link_status(pAdapter,
11656 mac,
11657 eTDLS_LINK_CONNECTING,
11658 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011659
Jeff Johnsond75fe012013-04-06 10:53:06 -070011660 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011661 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011662 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011664 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011665 if(StaParams->htcap_present)
11666 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011668 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011670 "ht_capa->extended_capabilities: %0x",
11671 StaParams->HTCap.extendedHtCapInfo);
11672 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011674 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011676 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011677 if(StaParams->vhtcap_present)
11678 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011680 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
11681 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
11682 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
11683 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011684 {
11685 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011687 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011689 "[%d]: %x ", i, StaParams->supported_rates[i]);
11690 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070011691 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011692 else if ((1 == update) && (NULL == StaParams))
11693 {
11694 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11695 "%s : update is true, but staParams is NULL. Error!", __func__);
11696 return -EPERM;
11697 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011698
11699 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
11700
11701 if (!update)
11702 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011703 /*Before adding sta make sure that device exited from BMPS*/
11704 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
11705 {
11706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11707 "%s: Adding tdls peer sta. Disable BMPS", __func__);
11708 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
11709 if (status != VOS_STATUS_SUCCESS) {
11710 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
11711 }
11712 }
11713
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011714 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011715 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011716 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011717 hddLog(VOS_TRACE_LEVEL_ERROR,
11718 FL("Failed to add TDLS peer STA. Enable Bmps"));
11719 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011720 return -EPERM;
11721 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011722 }
11723 else
11724 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011725 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011726 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011727 if (ret != eHAL_STATUS_SUCCESS) {
11728 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
11729 return -EPERM;
11730 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011731 }
11732
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011733 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011734 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
11735
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011736 mutex_lock(&pHddCtx->tdls_lock);
11737 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
11738
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011739 if ((pTdlsPeer != NULL) &&
11740 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011741 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011742 hddLog(VOS_TRACE_LEVEL_ERROR,
11743 FL("peer link status %u"), pTdlsPeer->link_status);
11744 mutex_unlock(&pHddCtx->tdls_lock);
11745 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011746 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011747 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011748
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011749 if (ret <= 0)
11750 {
11751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11752 "%s: timeout waiting for tdls add station indication %ld",
11753 __func__, ret);
11754 goto error;
11755 }
11756
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011757 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
11758 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011760 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011761 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011762 }
11763
11764 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070011765
11766error:
Atul Mittal115287b2014-07-08 13:26:33 +053011767 wlan_hdd_tdls_set_link_status(pAdapter,
11768 mac,
11769 eTDLS_LINK_IDLE,
11770 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011771 return -EPERM;
11772
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011773}
11774#endif
11775
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011776static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011777 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011778#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11779 const u8 *mac,
11780#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011781 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011782#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011783 struct station_parameters *params)
11784{
11785 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011786 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011787 hdd_context_t *pHddCtx;
11788 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011789 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011790 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011791#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011792 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011793 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011794 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011795 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011796#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011797
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011798 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011799
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011800 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011801 if ((NULL == pAdapter))
11802 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011804 "invalid adapter ");
11805 return -EINVAL;
11806 }
11807
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011808 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11809 TRACE_CODE_HDD_CHANGE_STATION,
11810 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053011811 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011812
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011813 ret = wlan_hdd_validate_context(pHddCtx);
11814 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053011815 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011816 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011817 }
11818
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011819 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11820
11821 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011822 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011823 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11824 "invalid HDD station context");
11825 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011826 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011827 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
11828
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011829 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11830 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070011831 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011832 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070011833 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011834 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070011835 WLANTL_STA_AUTHENTICATED);
11836
Gopichand Nakkala29149562013-05-10 21:43:41 +053011837 if (status != VOS_STATUS_SUCCESS)
11838 {
11839 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11840 "%s: Not able to change TL state to AUTHENTICATED", __func__);
11841 return -EINVAL;
11842 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011843 }
11844 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070011845 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
11846 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011847#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011848 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11849 StaParams.capability = params->capability;
11850 StaParams.uapsd_queues = params->uapsd_queues;
11851 StaParams.max_sp = params->max_sp;
11852
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011853 /* Convert (first channel , number of channels) tuple to
11854 * the total list of channels. This goes with the assumption
11855 * that if the first channel is < 14, then the next channels
11856 * are an incremental of 1 else an incremental of 4 till the number
11857 * of channels.
11858 */
11859 if (0 != params->supported_channels_len) {
11860 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11861 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11862 {
11863 int wifi_chan_index;
11864 StaParams.supported_channels[j] = params->supported_channels[i];
11865 wifi_chan_index =
11866 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11867 no_of_channels = params->supported_channels[i+1];
11868 for(k=1; k <= no_of_channels; k++)
11869 {
11870 StaParams.supported_channels[j+1] =
11871 StaParams.supported_channels[j] + wifi_chan_index;
11872 j+=1;
11873 }
11874 }
11875 StaParams.supported_channels_len = j;
11876 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053011877 if (params->supported_oper_classes_len >
11878 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
11879 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11880 "received oper classes:%d, resetting it to max supported %d",
11881 params->supported_oper_classes_len,
11882 SIR_MAC_MAX_SUPP_OPER_CLASSES);
11883 params->supported_oper_classes_len =
11884 SIR_MAC_MAX_SUPP_OPER_CLASSES;
11885 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011886 vos_mem_copy(StaParams.supported_oper_classes,
11887 params->supported_oper_classes,
11888 params->supported_oper_classes_len);
11889 StaParams.supported_oper_classes_len =
11890 params->supported_oper_classes_len;
11891
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053011892 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
11893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11894 "received extn capabilities:%d, resetting it to max supported",
11895 params->ext_capab_len);
11896 params->ext_capab_len = sizeof(StaParams.extn_capability);
11897 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011898 if (0 != params->ext_capab_len)
11899 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053011900 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011901
11902 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011903 {
11904 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011905 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011906 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011907
11908 StaParams.supported_rates_len = params->supported_rates_len;
11909
11910 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11911 * The supported_rates array , for all the structures propogating till Add Sta
11912 * to the firmware has to be modified , if the supplicant (ieee80211) is
11913 * modified to send more rates.
11914 */
11915
11916 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11917 */
11918 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11919 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11920
11921 if (0 != StaParams.supported_rates_len) {
11922 int i = 0;
11923 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11924 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011926 "Supported Rates with Length %d", StaParams.supported_rates_len);
11927 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011929 "[%d]: %0x", i, StaParams.supported_rates[i]);
11930 }
11931
11932 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011933 {
11934 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011935 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011936 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011937
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011938 if (0 != params->ext_capab_len ) {
11939 /*Define A Macro : TODO Sunil*/
11940 if ((1<<4) & StaParams.extn_capability[3]) {
11941 isBufSta = 1;
11942 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011943 /* TDLS Channel Switching Support */
11944 if ((1<<6) & StaParams.extn_capability[3]) {
11945 isOffChannelSupported = 1;
11946 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011947 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011948
11949 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053011950 (params->ht_capa || params->vht_capa ||
11951 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011952 /* TDLS Peer is WME/QoS capable */
11953 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011954
11955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11956 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
11957 __func__, isQosWmmSta, StaParams.htcap_present);
11958
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011959 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11960 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011961 isOffChannelSupported,
11962 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011963
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011964 if (VOS_STATUS_SUCCESS != status) {
11965 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11966 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11967 return -EINVAL;
11968 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011969 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11970
11971 if (VOS_STATUS_SUCCESS != status) {
11972 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11973 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11974 return -EINVAL;
11975 }
11976 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011977#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011978 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011979 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011980 return status;
11981}
11982
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011983#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11984static int wlan_hdd_change_station(struct wiphy *wiphy,
11985 struct net_device *dev,
11986 const u8 *mac,
11987 struct station_parameters *params)
11988#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011989static int wlan_hdd_change_station(struct wiphy *wiphy,
11990 struct net_device *dev,
11991 u8 *mac,
11992 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011993#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011994{
11995 int ret;
11996
11997 vos_ssr_protect(__func__);
11998 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11999 vos_ssr_unprotect(__func__);
12000
12001 return ret;
12002}
12003
Jeff Johnson295189b2012-06-20 16:38:30 -070012004/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012005 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012006 * This function is used to initialize the key information
12007 */
12008#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012009static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012010 struct net_device *ndev,
12011 u8 key_index, bool pairwise,
12012 const u8 *mac_addr,
12013 struct key_params *params
12014 )
12015#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012016static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012017 struct net_device *ndev,
12018 u8 key_index, const u8 *mac_addr,
12019 struct key_params *params
12020 )
12021#endif
12022{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012023 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012024 tCsrRoamSetKey setKey;
12025 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012026 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012027 v_U32_t roamId= 0xFF;
12028 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012029 hdd_hostapd_state_t *pHostapdState;
12030 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012031 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012032 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012033
12034 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012035
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012036 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12037 TRACE_CODE_HDD_CFG80211_ADD_KEY,
12038 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012039 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12040 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012041 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012042 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012043 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012044 }
12045
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012046 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12047 __func__, hdd_device_modetoString(pAdapter->device_mode),
12048 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012049
12050 if (CSR_MAX_NUM_KEY <= key_index)
12051 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012052 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012053 key_index);
12054
12055 return -EINVAL;
12056 }
12057
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012058 if (CSR_MAX_KEY_LEN < params->key_len)
12059 {
12060 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
12061 params->key_len);
12062
12063 return -EINVAL;
12064 }
12065
12066 hddLog(VOS_TRACE_LEVEL_INFO,
12067 "%s: called with key index = %d & key length %d",
12068 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012069
12070 /*extract key idx, key len and key*/
12071 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12072 setKey.keyId = key_index;
12073 setKey.keyLength = params->key_len;
12074 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
12075
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012076 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012077 {
12078 case WLAN_CIPHER_SUITE_WEP40:
12079 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12080 break;
12081
12082 case WLAN_CIPHER_SUITE_WEP104:
12083 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
12084 break;
12085
12086 case WLAN_CIPHER_SUITE_TKIP:
12087 {
12088 u8 *pKey = &setKey.Key[0];
12089 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
12090
12091 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
12092
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012093 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070012094
12095 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012096 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012097 |--------------|----------|----------|
12098 <---16bytes---><--8bytes--><--8bytes-->
12099
12100 */
12101 /*Sme expects the 32 bytes key to be in the below order
12102
12103 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012104 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012105 |--------------|----------|----------|
12106 <---16bytes---><--8bytes--><--8bytes-->
12107 */
12108 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012109 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070012110
12111 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012112 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012113
12114 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012115 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012116
12117
12118 break;
12119 }
12120
12121 case WLAN_CIPHER_SUITE_CCMP:
12122 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
12123 break;
12124
12125#ifdef FEATURE_WLAN_WAPI
12126 case WLAN_CIPHER_SUITE_SMS4:
12127 {
12128 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12129 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
12130 params->key, params->key_len);
12131 return 0;
12132 }
12133#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012134
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012135#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012136 case WLAN_CIPHER_SUITE_KRK:
12137 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
12138 break;
12139#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012140
12141#ifdef WLAN_FEATURE_11W
12142 case WLAN_CIPHER_SUITE_AES_CMAC:
12143 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070012144 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070012145#endif
12146
Jeff Johnson295189b2012-06-20 16:38:30 -070012147 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012148 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012149 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012150 status = -EOPNOTSUPP;
12151 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012152 }
12153
12154 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
12155 __func__, setKey.encType);
12156
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012157 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070012158#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12159 (!pairwise)
12160#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012161 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070012162#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012163 )
12164 {
12165 /* set group key*/
12166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12167 "%s- %d: setting Broadcast key",
12168 __func__, __LINE__);
12169 setKey.keyDirection = eSIR_RX_ONLY;
12170 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12171 }
12172 else
12173 {
12174 /* set pairwise key*/
12175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12176 "%s- %d: setting pairwise key",
12177 __func__, __LINE__);
12178 setKey.keyDirection = eSIR_TX_RX;
12179 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
12180 }
12181 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
12182 {
12183 setKey.keyDirection = eSIR_TX_RX;
12184 /*Set the group key*/
12185 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12186 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070012187
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012188 if ( 0 != status )
12189 {
12190 hddLog(VOS_TRACE_LEVEL_ERROR,
12191 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012192 status = -EINVAL;
12193 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012194 }
12195 /*Save the keys here and call sme_RoamSetKey for setting
12196 the PTK after peer joins the IBSS network*/
12197 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
12198 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012199 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012200 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053012201 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
12202 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
12203 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012204 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012205 if( pHostapdState->bssState == BSS_START )
12206 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012207 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12208 vos_status = wlan_hdd_check_ula_done(pAdapter);
12209
12210 if ( vos_status != VOS_STATUS_SUCCESS )
12211 {
12212 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12213 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12214 __LINE__, vos_status );
12215
12216 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12217
12218 status = -EINVAL;
12219 goto end;
12220 }
12221
Jeff Johnson295189b2012-06-20 16:38:30 -070012222 status = WLANSAP_SetKeySta( pVosContext, &setKey);
12223
12224 if ( status != eHAL_STATUS_SUCCESS )
12225 {
12226 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12227 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12228 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012229 status = -EINVAL;
12230 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012231 }
12232 }
12233
12234 /* Saving WEP keys */
12235 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
12236 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
12237 {
12238 //Save the wep key in ap context. Issue setkey after the BSS is started.
12239 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12240 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
12241 }
12242 else
12243 {
12244 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012245 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012246 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
12247 }
12248 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012249 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
12250 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012251 {
12252 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12253 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12254
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012255#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12256 if (!pairwise)
12257#else
12258 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
12259#endif
12260 {
12261 /* set group key*/
12262 if (pHddStaCtx->roam_info.deferKeyComplete)
12263 {
12264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12265 "%s- %d: Perform Set key Complete",
12266 __func__, __LINE__);
12267 hdd_PerformRoamSetKeyComplete(pAdapter);
12268 }
12269 }
12270
Jeff Johnson295189b2012-06-20 16:38:30 -070012271 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
12272
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080012273 pWextState->roamProfile.Keys.defaultIndex = key_index;
12274
12275
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012276 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012277 params->key, params->key_len);
12278
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012279
Jeff Johnson295189b2012-06-20 16:38:30 -070012280 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12281
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012282 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012283 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012284 __func__, setKey.peerMac[0], setKey.peerMac[1],
12285 setKey.peerMac[2], setKey.peerMac[3],
12286 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012287 setKey.keyDirection);
12288
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012289 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053012290
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012291 if ( vos_status != VOS_STATUS_SUCCESS )
12292 {
12293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012294 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12295 __LINE__, vos_status );
12296
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012297 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012298
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012299 status = -EINVAL;
12300 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012301
12302 }
12303
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012304#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012305 /* The supplicant may attempt to set the PTK once pre-authentication
12306 is done. Save the key in the UMAC and include it in the ADD BSS
12307 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012308 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012309 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012310 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012311 hddLog(VOS_TRACE_LEVEL_INFO_MED,
12312 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012313 status = 0;
12314 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012315 }
12316 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
12317 {
12318 hddLog(VOS_TRACE_LEVEL_ERROR,
12319 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012320 status = -EINVAL;
12321 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012322 }
12323#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070012324
12325 /* issue set key request to SME*/
12326 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12327 pAdapter->sessionId, &setKey, &roamId );
12328
12329 if ( 0 != status )
12330 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012331 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012332 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
12333 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012334 status = -EINVAL;
12335 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012336 }
12337
12338
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012339 /* in case of IBSS as there was no information available about WEP keys during
12340 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070012341 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012342 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
12343 !( ( IW_AUTH_KEY_MGMT_802_1X
12344 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070012345 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
12346 )
12347 &&
12348 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
12349 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
12350 )
12351 )
12352 {
12353 setKey.keyDirection = eSIR_RX_ONLY;
12354 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12355
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012356 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012357 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012358 __func__, setKey.peerMac[0], setKey.peerMac[1],
12359 setKey.peerMac[2], setKey.peerMac[3],
12360 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012361 setKey.keyDirection);
12362
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012363 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012364 pAdapter->sessionId, &setKey, &roamId );
12365
12366 if ( 0 != status )
12367 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012368 hddLog(VOS_TRACE_LEVEL_ERROR,
12369 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012370 __func__, status);
12371 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012372 status = -EINVAL;
12373 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012374 }
12375 }
12376 }
12377
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012378end:
12379 /* Need to clear any trace of key value in the memory.
12380 * Thus zero out the memory even though it is local
12381 * variable.
12382 */
12383 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012384 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012385 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012386}
12387
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012388#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12389static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12390 struct net_device *ndev,
12391 u8 key_index, bool pairwise,
12392 const u8 *mac_addr,
12393 struct key_params *params
12394 )
12395#else
12396static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12397 struct net_device *ndev,
12398 u8 key_index, const u8 *mac_addr,
12399 struct key_params *params
12400 )
12401#endif
12402{
12403 int ret;
12404 vos_ssr_protect(__func__);
12405#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12406 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
12407 mac_addr, params);
12408#else
12409 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
12410 params);
12411#endif
12412 vos_ssr_unprotect(__func__);
12413
12414 return ret;
12415}
12416
Jeff Johnson295189b2012-06-20 16:38:30 -070012417/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012418 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012419 * This function is used to get the key information
12420 */
12421#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012422static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012423 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012424 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012425 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012426 const u8 *mac_addr, void *cookie,
12427 void (*callback)(void *cookie, struct key_params*)
12428 )
12429#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012430static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012431 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012432 struct net_device *ndev,
12433 u8 key_index, const u8 *mac_addr, void *cookie,
12434 void (*callback)(void *cookie, struct key_params*)
12435 )
12436#endif
12437{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012438 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012439 hdd_wext_state_t *pWextState = NULL;
12440 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012441 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012442 hdd_context_t *pHddCtx;
12443 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012444
12445 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012446
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012447 if (NULL == pAdapter)
12448 {
12449 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12450 "%s: HDD adapter is Null", __func__);
12451 return -ENODEV;
12452 }
12453
12454 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12455 ret = wlan_hdd_validate_context(pHddCtx);
12456 if (0 != ret)
12457 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012458 return ret;
12459 }
12460
12461 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12462 pRoamProfile = &(pWextState->roamProfile);
12463
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012464 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12465 __func__, hdd_device_modetoString(pAdapter->device_mode),
12466 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012467
Jeff Johnson295189b2012-06-20 16:38:30 -070012468 memset(&params, 0, sizeof(params));
12469
12470 if (CSR_MAX_NUM_KEY <= key_index)
12471 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012472 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012473 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012474 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012475
12476 switch(pRoamProfile->EncryptionType.encryptionType[0])
12477 {
12478 case eCSR_ENCRYPT_TYPE_NONE:
12479 params.cipher = IW_AUTH_CIPHER_NONE;
12480 break;
12481
12482 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
12483 case eCSR_ENCRYPT_TYPE_WEP40:
12484 params.cipher = WLAN_CIPHER_SUITE_WEP40;
12485 break;
12486
12487 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
12488 case eCSR_ENCRYPT_TYPE_WEP104:
12489 params.cipher = WLAN_CIPHER_SUITE_WEP104;
12490 break;
12491
12492 case eCSR_ENCRYPT_TYPE_TKIP:
12493 params.cipher = WLAN_CIPHER_SUITE_TKIP;
12494 break;
12495
12496 case eCSR_ENCRYPT_TYPE_AES:
12497 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
12498 break;
12499
12500 default:
12501 params.cipher = IW_AUTH_CIPHER_NONE;
12502 break;
12503 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012504
c_hpothuaaf19692014-05-17 17:01:48 +053012505 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12506 TRACE_CODE_HDD_CFG80211_GET_KEY,
12507 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012508
Jeff Johnson295189b2012-06-20 16:38:30 -070012509 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
12510 params.seq_len = 0;
12511 params.seq = NULL;
12512 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
12513 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012514 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012515 return 0;
12516}
12517
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012518#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12519static int wlan_hdd_cfg80211_get_key(
12520 struct wiphy *wiphy,
12521 struct net_device *ndev,
12522 u8 key_index, bool pairwise,
12523 const u8 *mac_addr, void *cookie,
12524 void (*callback)(void *cookie, struct key_params*)
12525 )
12526#else
12527static int wlan_hdd_cfg80211_get_key(
12528 struct wiphy *wiphy,
12529 struct net_device *ndev,
12530 u8 key_index, const u8 *mac_addr, void *cookie,
12531 void (*callback)(void *cookie, struct key_params*)
12532 )
12533#endif
12534{
12535 int ret;
12536
12537 vos_ssr_protect(__func__);
12538#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12539 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
12540 mac_addr, cookie, callback);
12541#else
12542 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
12543 callback);
12544#endif
12545 vos_ssr_unprotect(__func__);
12546
12547 return ret;
12548}
12549
Jeff Johnson295189b2012-06-20 16:38:30 -070012550/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012551 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012552 * This function is used to delete the key information
12553 */
12554#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012555static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012556 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012557 u8 key_index,
12558 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012559 const u8 *mac_addr
12560 )
12561#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012562static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012563 struct net_device *ndev,
12564 u8 key_index,
12565 const u8 *mac_addr
12566 )
12567#endif
12568{
12569 int status = 0;
12570
12571 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012572 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070012573 //it is observed that this is invalidating peer
12574 //key index whenever re-key is done. This is affecting data link.
12575 //It should be ok to ignore del_key.
12576#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012577 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
12578 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012579 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12580 tCsrRoamSetKey setKey;
12581 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012582
Jeff Johnson295189b2012-06-20 16:38:30 -070012583 ENTER();
12584
12585 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
12586 __func__,pAdapter->device_mode);
12587
12588 if (CSR_MAX_NUM_KEY <= key_index)
12589 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012590 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012591 key_index);
12592
12593 return -EINVAL;
12594 }
12595
12596 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12597 setKey.keyId = key_index;
12598
12599 if (mac_addr)
12600 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
12601 else
12602 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
12603
12604 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
12605
12606 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012607 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012608 )
12609 {
12610
12611 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070012612 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
12613 if( pHostapdState->bssState == BSS_START)
12614 {
12615 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012616
Jeff Johnson295189b2012-06-20 16:38:30 -070012617 if ( status != eHAL_STATUS_SUCCESS )
12618 {
12619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12620 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12621 __LINE__, status );
12622 }
12623 }
12624 }
12625 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012626 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070012627 )
12628 {
12629 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12630
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012631 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12632
12633 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012634 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012635 __func__, setKey.peerMac[0], setKey.peerMac[1],
12636 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070012637 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012638 if(pAdapter->sessionCtx.station.conn_info.connState ==
12639 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070012640 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012641 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012642 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012643
Jeff Johnson295189b2012-06-20 16:38:30 -070012644 if ( 0 != status )
12645 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012646 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012647 "%s: sme_RoamSetKey failure, returned %d",
12648 __func__, status);
12649 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12650 return -EINVAL;
12651 }
12652 }
12653 }
12654#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012655 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012656 return status;
12657}
12658
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012659#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12660static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12661 struct net_device *ndev,
12662 u8 key_index,
12663 bool pairwise,
12664 const u8 *mac_addr
12665 )
12666#else
12667static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12668 struct net_device *ndev,
12669 u8 key_index,
12670 const u8 *mac_addr
12671 )
12672#endif
12673{
12674 int ret;
12675
12676 vos_ssr_protect(__func__);
12677#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12678 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
12679 mac_addr);
12680#else
12681 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
12682#endif
12683 vos_ssr_unprotect(__func__);
12684
12685 return ret;
12686}
12687
Jeff Johnson295189b2012-06-20 16:38:30 -070012688/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012689 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012690 * This function is used to set the default tx key index
12691 */
12692#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012693static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012694 struct net_device *ndev,
12695 u8 key_index,
12696 bool unicast, bool multicast)
12697#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012698static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012699 struct net_device *ndev,
12700 u8 key_index)
12701#endif
12702{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012703 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012704 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012705 hdd_wext_state_t *pWextState;
12706 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012707 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012708
12709 ENTER();
12710
Gopichand Nakkala29149562013-05-10 21:43:41 +053012711 if ((NULL == pAdapter))
12712 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012713 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012714 "invalid adapter");
12715 return -EINVAL;
12716 }
12717
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012718 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12719 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
12720 pAdapter->sessionId, key_index));
12721
Gopichand Nakkala29149562013-05-10 21:43:41 +053012722 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12723 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12724
12725 if ((NULL == pWextState) || (NULL == pHddStaCtx))
12726 {
12727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12728 "invalid Wext state or HDD context");
12729 return -EINVAL;
12730 }
12731
Arif Hussain6d2a3322013-11-17 19:50:10 -080012732 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012733 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012734
Jeff Johnson295189b2012-06-20 16:38:30 -070012735 if (CSR_MAX_NUM_KEY <= key_index)
12736 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012737 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012738 key_index);
12739
12740 return -EINVAL;
12741 }
12742
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012743 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12744 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012745 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012746 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012747 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012748 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012749
Jeff Johnson295189b2012-06-20 16:38:30 -070012750 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012751 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012752 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012753 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012754 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080012755 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012756 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080012757 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070012758 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012759 {
12760 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070012761 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012762
Jeff Johnson295189b2012-06-20 16:38:30 -070012763 tCsrRoamSetKey setKey;
12764 v_U32_t roamId= 0xFF;
12765 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012766
12767 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012768 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012769
Jeff Johnson295189b2012-06-20 16:38:30 -070012770 Keys->defaultIndex = (u8)key_index;
12771 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12772 setKey.keyId = key_index;
12773 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012774
12775 vos_mem_copy(&setKey.Key[0],
12776 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012777 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012778
Gopichand Nakkala29149562013-05-10 21:43:41 +053012779 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012780
12781 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070012782 &pHddStaCtx->conn_info.bssId[0],
12783 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012784
Gopichand Nakkala29149562013-05-10 21:43:41 +053012785 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
12786 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
12787 eCSR_ENCRYPT_TYPE_WEP104)
12788 {
12789 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
12790 even though ap is configured for WEP-40 encryption. In this canse the key length
12791 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
12792 type(104) and switching encryption type to 40*/
12793 pWextState->roamProfile.EncryptionType.encryptionType[0] =
12794 eCSR_ENCRYPT_TYPE_WEP40;
12795 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
12796 eCSR_ENCRYPT_TYPE_WEP40;
12797 }
12798
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012799 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012800 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012801
Jeff Johnson295189b2012-06-20 16:38:30 -070012802 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012803 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012804 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012805
Jeff Johnson295189b2012-06-20 16:38:30 -070012806 if ( 0 != status )
12807 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012808 hddLog(VOS_TRACE_LEVEL_ERROR,
12809 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012810 status);
12811 return -EINVAL;
12812 }
12813 }
12814 }
12815
12816 /* In SoftAp mode setting key direction for default mode */
12817 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
12818 {
12819 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
12820 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
12821 (eCSR_ENCRYPT_TYPE_AES !=
12822 pWextState->roamProfile.EncryptionType.encryptionType[0])
12823 )
12824 {
12825 /* Saving key direction for default key index to TX default */
12826 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12827 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
12828 }
12829 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012830 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012831 return status;
12832}
12833
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012834#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12835static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12836 struct net_device *ndev,
12837 u8 key_index,
12838 bool unicast, bool multicast)
12839#else
12840static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12841 struct net_device *ndev,
12842 u8 key_index)
12843#endif
12844{
12845 int ret;
12846 vos_ssr_protect(__func__);
12847#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12848 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
12849 multicast);
12850#else
12851 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
12852#endif
12853 vos_ssr_unprotect(__func__);
12854
12855 return ret;
12856}
12857
Jeff Johnson295189b2012-06-20 16:38:30 -070012858/*
12859 * FUNCTION: wlan_hdd_cfg80211_inform_bss
12860 * This function is used to inform the BSS details to nl80211 interface.
12861 */
12862static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
12863 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
12864{
12865 struct net_device *dev = pAdapter->dev;
12866 struct wireless_dev *wdev = dev->ieee80211_ptr;
12867 struct wiphy *wiphy = wdev->wiphy;
12868 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12869 int chan_no;
12870 int ie_length;
12871 const char *ie;
12872 unsigned int freq;
12873 struct ieee80211_channel *chan;
12874 int rssi = 0;
12875 struct cfg80211_bss *bss = NULL;
12876
Jeff Johnson295189b2012-06-20 16:38:30 -070012877 if( NULL == pBssDesc )
12878 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012879 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012880 return bss;
12881 }
12882
12883 chan_no = pBssDesc->channelId;
12884 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12885 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12886
12887 if( NULL == ie )
12888 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012889 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012890 return bss;
12891 }
12892
12893#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12894 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12895 {
12896 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12897 }
12898 else
12899 {
12900 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12901 }
12902#else
12903 freq = ieee80211_channel_to_frequency(chan_no);
12904#endif
12905
12906 chan = __ieee80211_get_channel(wiphy, freq);
12907
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012908 if (!chan) {
12909 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12910 return NULL;
12911 }
12912
Abhishek Singhaee43942014-06-16 18:55:47 +053012913 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012914
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012915 return cfg80211_inform_bss(wiphy, chan,
12916#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12917 CFG80211_BSS_FTYPE_UNKNOWN,
12918#endif
12919 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012920 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012921 pBssDesc->capabilityInfo,
12922 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012923 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012924}
12925
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012926/*
12927 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
12928 * interface that BSS might have been lost.
12929 * @pAdapter: adaptor
12930 * @bssid: bssid which might have been lost
12931 *
12932 * Return: bss which is unlinked from kernel cache
12933 */
12934struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
12935 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
12936{
12937 struct net_device *dev = pAdapter->dev;
12938 struct wireless_dev *wdev = dev->ieee80211_ptr;
12939 struct wiphy *wiphy = wdev->wiphy;
12940 struct cfg80211_bss *bss = NULL;
12941
Abhishek Singh5a597e62016-12-05 15:16:30 +053012942 bss = hdd_get_bss_entry(wiphy,
12943 NULL, bssid,
12944 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012945 if (bss == NULL) {
12946 hddLog(LOGE, FL("BSS not present"));
12947 } else {
12948 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
12949 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
12950 cfg80211_unlink_bss(wiphy, bss);
12951 }
12952 return bss;
12953}
Jeff Johnson295189b2012-06-20 16:38:30 -070012954
12955
12956/*
12957 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12958 * This function is used to inform the BSS details to nl80211 interface.
12959 */
12960struct cfg80211_bss*
12961wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
12962 tSirBssDescription *bss_desc
12963 )
12964{
12965 /*
12966 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
12967 already exists in bss data base of cfg80211 for that particular BSS ID.
12968 Using cfg80211_inform_bss_frame to update the bss entry instead of
12969 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
12970 now there is no possibility to get the mgmt(probe response) frame from PE,
12971 converting bss_desc to ieee80211_mgmt(probe response) and passing to
12972 cfg80211_inform_bss_frame.
12973 */
12974 struct net_device *dev = pAdapter->dev;
12975 struct wireless_dev *wdev = dev->ieee80211_ptr;
12976 struct wiphy *wiphy = wdev->wiphy;
12977 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012978#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12979 qcom_ie_age *qie_age = NULL;
12980 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12981#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012982 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012983#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012984 const char *ie =
12985 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12986 unsigned int freq;
12987 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012988 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012989 struct cfg80211_bss *bss_status = NULL;
12990 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
12991 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070012992 hdd_context_t *pHddCtx;
12993 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070012994#ifdef WLAN_OPEN_SOURCE
12995 struct timespec ts;
12996#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012997
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012998
Wilson Yangf80a0542013-10-07 13:02:37 -070012999 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13000 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070013001 if (0 != status)
13002 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013003 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013004 }
13005
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013006 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070013007 if (!mgmt)
13008 {
13009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13010 "%s: memory allocation failed ", __func__);
13011 return NULL;
13012 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013013
Jeff Johnson295189b2012-06-20 16:38:30 -070013014 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013015
13016#ifdef WLAN_OPEN_SOURCE
13017 /* Android does not want the timestamp from the frame.
13018 Instead it wants a monotonic increasing value */
13019 get_monotonic_boottime(&ts);
13020 mgmt->u.probe_resp.timestamp =
13021 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
13022#else
13023 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070013024 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
13025 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070013026
13027#endif
13028
Jeff Johnson295189b2012-06-20 16:38:30 -070013029 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
13030 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013031
13032#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13033 /* GPS Requirement: need age ie per entry. Using vendor specific. */
13034 /* Assuming this is the last IE, copy at the end */
13035 ie_length -=sizeof(qcom_ie_age);
13036 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
13037 qie_age->element_id = QCOM_VENDOR_IE_ID;
13038 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
13039 qie_age->oui_1 = QCOM_OUI1;
13040 qie_age->oui_2 = QCOM_OUI2;
13041 qie_age->oui_3 = QCOM_OUI3;
13042 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053013043 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
13044 * bss related timestamp is in units of ms. Due to this when scan results
13045 * are sent to lowi the scan age is high.To address this, send age in units
13046 * of 1/10 ms.
13047 */
13048 qie_age->age = (vos_timer_get_system_time() -
13049 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013050#endif
13051
Jeff Johnson295189b2012-06-20 16:38:30 -070013052 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053013053 if (bss_desc->fProbeRsp)
13054 {
13055 mgmt->frame_control |=
13056 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
13057 }
13058 else
13059 {
13060 mgmt->frame_control |=
13061 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
13062 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013063
13064#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013065 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013066 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
13067 {
13068 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
13069 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013070 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013071 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
13072
13073 {
13074 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
13075 }
13076 else
13077 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
13079 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070013080 kfree(mgmt);
13081 return NULL;
13082 }
13083#else
13084 freq = ieee80211_channel_to_frequency(chan_no);
13085#endif
13086 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013087 /*when the band is changed on the fly using the GUI, three things are done
13088 * 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)
13089 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
13090 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
13091 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
13092 * and discards the channels correponding to previous band and calls back with zero bss results.
13093 * 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
13094 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
13095 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
13096 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
13097 * So drop the bss and continue to next bss.
13098 */
13099 if(chan == NULL)
13100 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053013101 hddLog(VOS_TRACE_LEVEL_ERROR,
13102 FL("chan pointer is NULL, chan_no: %d freq: %d"),
13103 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070013104 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013105 return NULL;
13106 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053013107 /*To keep the rssi icon of the connected AP in the scan window
13108 *and the rssi icon of the wireless networks in sync
13109 * */
13110 if (( eConnectionState_Associated ==
13111 pAdapter->sessionCtx.station.conn_info.connState ) &&
13112 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
13113 pAdapter->sessionCtx.station.conn_info.bssId,
13114 WNI_CFG_BSSID_LEN)) &&
13115 (pHddCtx->hdd_wlan_suspended == FALSE))
13116 {
13117 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
13118 rssi = (pAdapter->rssi * 100);
13119 }
13120 else
13121 {
13122 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
13123 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013124
Nirav Shah20ac06f2013-12-12 18:14:06 +053013125 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053013126 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
13127 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053013128
Jeff Johnson295189b2012-06-20 16:38:30 -070013129 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
13130 frame_len, rssi, GFP_KERNEL);
13131 kfree(mgmt);
13132 return bss_status;
13133}
13134
13135/*
13136 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
13137 * This function is used to update the BSS data base of CFG8011
13138 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013139struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013140 tCsrRoamInfo *pRoamInfo
13141 )
13142{
13143 tCsrRoamConnectedProfile roamProfile;
13144 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13145 struct cfg80211_bss *bss = NULL;
13146
13147 ENTER();
13148
13149 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
13150 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
13151
13152 if (NULL != roamProfile.pBssDesc)
13153 {
Girish Gowlif4b68022014-08-28 23:18:57 +053013154 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13155 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070013156
13157 if (NULL == bss)
13158 {
13159 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
13160 __func__);
13161 }
13162
13163 sme_RoamFreeConnectProfile(hHal, &roamProfile);
13164 }
13165 else
13166 {
13167 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
13168 __func__);
13169 }
13170 return bss;
13171}
13172
13173/*
13174 * FUNCTION: wlan_hdd_cfg80211_update_bss
13175 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013176static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
13177 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070013178 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013179{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013180 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013181 tCsrScanResultInfo *pScanResult;
13182 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013183 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013184 tScanResultHandle pResult;
13185 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013186 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013187 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013188 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013189
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013190 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13191 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
13192 NO_SESSION, pAdapter->sessionId));
13193
Wilson Yangf80a0542013-10-07 13:02:37 -070013194 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013195 ret = wlan_hdd_validate_context(pHddCtx);
13196 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070013197 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013198 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070013199 }
13200
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013201 if (pAdapter->request != NULL)
13202 {
13203 if ((pAdapter->request->n_ssids == 1)
13204 && (pAdapter->request->ssids != NULL)
13205 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
13206 is_p2p_scan = true;
13207 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013208 /*
13209 * start getting scan results and populate cgf80211 BSS database
13210 */
13211 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
13212
13213 /* no scan results */
13214 if (NULL == pResult)
13215 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013216 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
13217 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013218 wlan_hdd_get_frame_logs(pAdapter,
13219 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070013220 return status;
13221 }
13222
13223 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
13224
13225 while (pScanResult)
13226 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013227 /*
13228 * cfg80211_inform_bss() is not updating ie field of bss entry, if
13229 * entry already exists in bss data base of cfg80211 for that
13230 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
13231 * bss entry instead of cfg80211_inform_bss, But this call expects
13232 * mgmt packet as input. As of now there is no possibility to get
13233 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070013234 * ieee80211_mgmt(probe response) and passing to c
13235 * fg80211_inform_bss_frame.
13236 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013237 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
13238 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
13239 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013240 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13241 continue; //Skip the non p2p bss entries
13242 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013243 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13244 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013245
Jeff Johnson295189b2012-06-20 16:38:30 -070013246
13247 if (NULL == bss_status)
13248 {
13249 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013250 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013251 }
13252 else
13253 {
Yue Maf49ba872013-08-19 12:04:25 -070013254 cfg80211_put_bss(
13255#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
13256 wiphy,
13257#endif
13258 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070013259 }
13260
13261 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13262 }
13263
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013264 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013265 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013266 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013267}
13268
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013269void
13270hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
13271{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013272 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080013273 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013274} /****** end hddPrintMacAddr() ******/
13275
13276void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013277hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013278{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013279 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013280 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013281 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
13282 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
13283 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013284} /****** end hddPrintPmkId() ******/
13285
13286//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
13287//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
13288
13289//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
13290//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
13291
13292#define dump_bssid(bssid) \
13293 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013294 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
13295 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013296 }
13297
13298#define dump_pmkid(pMac, pmkid) \
13299 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013300 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
13301 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013302 }
13303
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070013304#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013305/*
13306 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
13307 * This function is used to notify the supplicant of a new PMKSA candidate.
13308 */
13309int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013310 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013311 int index, bool preauth )
13312{
Jeff Johnsone7245742012-09-05 17:12:55 -070013313#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013314 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013315 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013316
13317 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070013318 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013319
13320 if( NULL == pRoamInfo )
13321 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013322 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013323 return -EINVAL;
13324 }
13325
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013326 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
13327 {
13328 dump_bssid(pRoamInfo->bssid);
13329 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013330 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013331 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013332#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013333 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013334}
13335#endif //FEATURE_WLAN_LFR
13336
Yue Maef608272013-04-08 23:09:17 -070013337#ifdef FEATURE_WLAN_LFR_METRICS
13338/*
13339 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
13340 * 802.11r/LFR metrics reporting function to report preauth initiation
13341 *
13342 */
13343#define MAX_LFR_METRICS_EVENT_LENGTH 100
13344VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
13345 tCsrRoamInfo *pRoamInfo)
13346{
13347 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13348 union iwreq_data wrqu;
13349
13350 ENTER();
13351
13352 if (NULL == pAdapter)
13353 {
13354 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13355 return VOS_STATUS_E_FAILURE;
13356 }
13357
13358 /* create the event */
13359 memset(&wrqu, 0, sizeof(wrqu));
13360 memset(metrics_notification, 0, sizeof(metrics_notification));
13361
13362 wrqu.data.pointer = metrics_notification;
13363 wrqu.data.length = scnprintf(metrics_notification,
13364 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
13365 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13366
13367 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13368
13369 EXIT();
13370
13371 return VOS_STATUS_SUCCESS;
13372}
13373
13374/*
13375 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
13376 * 802.11r/LFR metrics reporting function to report preauth completion
13377 * or failure
13378 */
13379VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
13380 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
13381{
13382 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13383 union iwreq_data wrqu;
13384
13385 ENTER();
13386
13387 if (NULL == pAdapter)
13388 {
13389 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13390 return VOS_STATUS_E_FAILURE;
13391 }
13392
13393 /* create the event */
13394 memset(&wrqu, 0, sizeof(wrqu));
13395 memset(metrics_notification, 0, sizeof(metrics_notification));
13396
13397 scnprintf(metrics_notification, sizeof(metrics_notification),
13398 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
13399 MAC_ADDR_ARRAY(pRoamInfo->bssid));
13400
13401 if (1 == preauth_status)
13402 strncat(metrics_notification, " TRUE", 5);
13403 else
13404 strncat(metrics_notification, " FALSE", 6);
13405
13406 wrqu.data.pointer = metrics_notification;
13407 wrqu.data.length = strlen(metrics_notification);
13408
13409 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13410
13411 EXIT();
13412
13413 return VOS_STATUS_SUCCESS;
13414}
13415
13416/*
13417 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
13418 * 802.11r/LFR metrics reporting function to report handover initiation
13419 *
13420 */
13421VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
13422 tCsrRoamInfo *pRoamInfo)
13423{
13424 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13425 union iwreq_data wrqu;
13426
13427 ENTER();
13428
13429 if (NULL == pAdapter)
13430 {
13431 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13432 return VOS_STATUS_E_FAILURE;
13433 }
13434
13435 /* create the event */
13436 memset(&wrqu, 0, sizeof(wrqu));
13437 memset(metrics_notification, 0, sizeof(metrics_notification));
13438
13439 wrqu.data.pointer = metrics_notification;
13440 wrqu.data.length = scnprintf(metrics_notification,
13441 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
13442 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13443
13444 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13445
13446 EXIT();
13447
13448 return VOS_STATUS_SUCCESS;
13449}
13450#endif
13451
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013452
13453/**
13454 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
13455 * @scan_req: scan request to be checked
13456 *
13457 * Return: true or false
13458 */
13459#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
13460static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13461 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013462 *scan_req, hdd_context_t
13463 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013464{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013465 if (!scan_req || !scan_req->wiphy ||
13466 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013467 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13468 return false;
13469 }
13470 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
13471 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
13472 return false;
13473 }
13474 return true;
13475}
13476#else
13477static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13478 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013479 *scan_req, hdd_context_t
13480 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013481{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013482 if (!scan_req || !scan_req->wiphy ||
13483 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013484 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13485 return false;
13486 }
13487 return true;
13488}
13489#endif
13490
13491
Jeff Johnson295189b2012-06-20 16:38:30 -070013492/*
13493 * FUNCTION: hdd_cfg80211_scan_done_callback
13494 * scanning callback function, called after finishing scan
13495 *
13496 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013497static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070013498 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
13499{
13500 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013501 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013502 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013503 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013504 struct cfg80211_scan_request *req = NULL;
13505 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013506 bool aborted = false;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013507#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13508 bool iface_down = false;
13509#endif
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013510 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013511 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013512 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013513
13514 ENTER();
13515
c_manjee1b4ab9a2016-10-26 11:36:55 +053013516 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
13517 !pAdapter->dev) {
13518 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
13519 return 0;
13520 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013521 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053013522 if (NULL == pHddCtx) {
13523 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013524 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013525 }
13526
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013527#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13528 if (!(pAdapter->dev->flags & IFF_UP))
13529 {
13530 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013531 iface_down = true;
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013532 }
13533#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013534 pScanInfo = &pHddCtx->scan_info;
13535
Jeff Johnson295189b2012-06-20 16:38:30 -070013536 hddLog(VOS_TRACE_LEVEL_INFO,
13537 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080013538 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013539 __func__, halHandle, pContext, (int) scanId, (int) status);
13540
Kiet Lamac06e2c2013-10-23 16:25:07 +053013541 pScanInfo->mScanPendingCounter = 0;
13542
Jeff Johnson295189b2012-06-20 16:38:30 -070013543 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013544 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070013545 &pScanInfo->scan_req_completion_event,
13546 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013547 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070013548 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013549 hddLog(VOS_TRACE_LEVEL_ERROR,
13550 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070013551 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013552 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013553 }
13554
Yue Maef608272013-04-08 23:09:17 -070013555 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070013556 {
13557 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013558 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013559 }
13560
13561 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013562 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070013563 {
13564 hddLog(VOS_TRACE_LEVEL_INFO,
13565 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080013566 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070013567 (int) scanId);
13568 }
13569
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013570#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013571 if (!iface_down)
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013572#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013573 {
13574 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
13575 pAdapter);
13576 if (0 > ret)
13577 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013578 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013579
Jeff Johnson295189b2012-06-20 16:38:30 -070013580 /* If any client wait scan result through WEXT
13581 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013582 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070013583 {
13584 /* The other scan request waiting for current scan finish
13585 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013586 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013587 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013588 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070013589 }
13590 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013591 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013592 {
13593 struct net_device *dev = pAdapter->dev;
13594 union iwreq_data wrqu;
13595 int we_event;
13596 char *msg;
13597
13598 memset(&wrqu, '\0', sizeof(wrqu));
13599 we_event = SIOCGIWSCAN;
13600 msg = NULL;
13601 wireless_send_event(dev, we_event, &wrqu, msg);
13602 }
13603 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013604 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013605
13606 /* Get the Scan Req */
13607 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053013608 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013609
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013610 /* Scan is no longer pending */
13611 pScanInfo->mScanPending = VOS_FALSE;
13612
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013613 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070013614 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013615#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13616 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
13617 iface_down ? "up" : "down");
13618#endif
13619
13620 if (pAdapter->dev) {
13621 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
13622 pAdapter->dev->name);
13623 }
mukul sharmae7041822015-12-03 15:09:21 +053013624 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070013625 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013626 }
13627
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013628 /* last_scan_timestamp is used to decide if new scan
13629 * is needed or not on station interface. If last station
13630 * scan time and new station scan time is less then
13631 * last_scan_timestamp ; driver will return cached scan.
13632 */
13633 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
13634 {
13635 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
13636
13637 if ( req->n_channels )
13638 {
13639 for (i = 0; i < req->n_channels ; i++ )
13640 {
13641 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
13642 }
13643 /* store no of channel scanned */
13644 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
13645 }
13646
13647 }
13648
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070013649 /*
13650 * cfg80211_scan_done informing NL80211 about completion
13651 * of scanning
13652 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013653 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
13654 {
13655 aborted = true;
13656 }
mukul sharmae7041822015-12-03 15:09:21 +053013657
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013658#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13659 if (!iface_down)
13660#endif
13661 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053013662
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013663 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070013664
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013665allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013666 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
13667 ) && (pHddCtx->spoofMacAddr.isEnabled
13668 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053013669 /* Generate new random mac addr for next scan */
13670 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053013671
13672 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
13673 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053013674 }
13675
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013676 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013677 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013678
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013679 /* Acquire wakelock to handle the case where APP's tries to suspend
13680 * immediatly after the driver gets connect request(i.e after scan)
13681 * from supplicant, this result in app's is suspending and not able
13682 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013683 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013684
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013685#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13686 if (!iface_down)
13687#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013688#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013689 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013690#endif
13691
Jeff Johnson295189b2012-06-20 16:38:30 -070013692 EXIT();
13693 return 0;
13694}
13695
13696/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053013697 * FUNCTION: hdd_isConnectionInProgress
13698 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013699 *
13700 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013701v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
13702 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013703{
13704 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13705 hdd_station_ctx_t *pHddStaCtx = NULL;
13706 hdd_adapter_t *pAdapter = NULL;
13707 VOS_STATUS status = 0;
13708 v_U8_t staId = 0;
13709 v_U8_t *staMac = NULL;
13710
13711 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13712
13713 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13714 {
13715 pAdapter = pAdapterNode->pAdapter;
13716
13717 if( pAdapter )
13718 {
13719 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013720 "%s: Adapter with device mode %s (%d) exists",
13721 __func__, hdd_device_modetoString(pAdapter->device_mode),
13722 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013723 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053013724 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13725 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
13726 (eConnectionState_Connecting ==
13727 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13728 {
13729 hddLog(VOS_TRACE_LEVEL_ERROR,
13730 "%s: %p(%d) Connection is in progress", __func__,
13731 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013732 if (session_id && reason)
13733 {
13734 *session_id = pAdapter->sessionId;
13735 *reason = eHDD_CONNECTION_IN_PROGRESS;
13736 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013737 return VOS_TRUE;
13738 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013739 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053013740 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013741 {
13742 hddLog(VOS_TRACE_LEVEL_ERROR,
13743 "%s: %p(%d) Reassociation is in progress", __func__,
13744 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013745 if (session_id && reason)
13746 {
13747 *session_id = pAdapter->sessionId;
13748 *reason = eHDD_REASSOC_IN_PROGRESS;
13749 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013750 return VOS_TRUE;
13751 }
13752 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013753 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13754 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013755 {
13756 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13757 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013758 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013759 {
13760 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
13761 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013762 "%s: client " MAC_ADDRESS_STR
13763 " is in the middle of WPS/EAPOL exchange.", __func__,
13764 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013765 if (session_id && reason)
13766 {
13767 *session_id = pAdapter->sessionId;
13768 *reason = eHDD_EAPOL_IN_PROGRESS;
13769 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013770 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013771 }
13772 }
13773 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
13774 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
13775 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013776 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13777 ptSapContext pSapCtx = NULL;
13778 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13779 if(pSapCtx == NULL){
13780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13781 FL("psapCtx is NULL"));
13782 return VOS_FALSE;
13783 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013784 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
13785 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013786 if ((pSapCtx->aStaInfo[staId].isUsed) &&
13787 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013788 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013789 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013790
13791 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013792 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
13793 "middle of WPS/EAPOL exchange.", __func__,
13794 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013795 if (session_id && reason)
13796 {
13797 *session_id = pAdapter->sessionId;
13798 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
13799 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013800 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013801 }
13802 }
13803 }
13804 }
13805 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13806 pAdapterNode = pNext;
13807 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013808 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013809}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013810
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013811/**
13812 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
13813 * to the Scan request
13814 * @scanRequest: Pointer to the csr scan request
13815 * @request: Pointer to the scan request from supplicant
13816 *
13817 * Return: None
13818 */
13819#ifdef CFG80211_SCAN_BSSID
13820static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13821 struct cfg80211_scan_request *request)
13822{
13823 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
13824}
13825#else
13826static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13827 struct cfg80211_scan_request *request)
13828{
13829}
13830#endif
13831
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013832/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013833 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070013834 * this scan respond to scan trigger and update cfg80211 scan database
13835 * later, scan dump command can be used to recieve scan results
13836 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013837int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013838#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13839 struct net_device *dev,
13840#endif
13841 struct cfg80211_scan_request *request)
13842{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013843 hdd_adapter_t *pAdapter = NULL;
13844 hdd_context_t *pHddCtx = NULL;
13845 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013846 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013847 tCsrScanRequest scanRequest;
13848 tANI_U8 *channelList = NULL, i;
13849 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013850 int status;
13851 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013852 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013853 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053013854 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013855 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013856 v_U8_t curr_session_id;
13857 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070013858
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013859#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
13860 struct net_device *dev = NULL;
13861 if (NULL == request)
13862 {
13863 hddLog(VOS_TRACE_LEVEL_ERROR,
13864 "%s: scan req param null", __func__);
13865 return -EINVAL;
13866 }
13867 dev = request->wdev->netdev;
13868#endif
13869
13870 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13871 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
13872 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13873
Jeff Johnson295189b2012-06-20 16:38:30 -070013874 ENTER();
13875
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013876 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13877 __func__, hdd_device_modetoString(pAdapter->device_mode),
13878 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013879
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013880 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013881 if (0 != status)
13882 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013883 return status;
13884 }
13885
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013886 if (NULL == pwextBuf)
13887 {
13888 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
13889 __func__);
13890 return -EIO;
13891 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013892 cfg_param = pHddCtx->cfg_ini;
13893 pScanInfo = &pHddCtx->scan_info;
13894
Jeff Johnson295189b2012-06-20 16:38:30 -070013895#ifdef WLAN_BTAMP_FEATURE
13896 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013897 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070013898 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013899 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013900 "%s: No scanning when AMP is on", __func__);
13901 return -EOPNOTSUPP;
13902 }
13903#endif
13904 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013905 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013906 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013907 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013908 "%s: Not scanning on device_mode = %s (%d)",
13909 __func__, hdd_device_modetoString(pAdapter->device_mode),
13910 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013911 return -EOPNOTSUPP;
13912 }
13913
13914 if (TRUE == pScanInfo->mScanPending)
13915 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013916 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
13917 {
13918 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
13919 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013920 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013921 }
13922
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053013923 // Don't allow scan if PNO scan is going on.
13924 if (pHddCtx->isPnoEnable)
13925 {
13926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13927 FL("pno scan in progress"));
13928 return -EBUSY;
13929 }
13930
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013931 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070013932 //Channel and action frame is pending
13933 //Otherwise Cancel Remain On Channel and allow Scan
13934 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013935 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070013936 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013937 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070013938 return -EBUSY;
13939 }
13940
Jeff Johnson295189b2012-06-20 16:38:30 -070013941 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
13942 {
13943 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080013944 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013945 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013946 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013947 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
13948 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013949 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013950 "%s: MAX TM Level Scan not allowed", __func__);
13951 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013952 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013953 }
13954 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
13955
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013956 /* Check if scan is allowed at this point of time.
13957 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053013958 if (TRUE == pHddCtx->btCoexModeSet)
13959 {
13960 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13961 FL("BTCoex Mode operation in progress"));
13962 return -EBUSY;
13963 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013964 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013965 {
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013966 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Scan not allowed"));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013967 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
13968 pHddCtx->last_scan_reject_reason != curr_reason ||
13969 !pHddCtx->last_scan_reject_timestamp)
13970 {
13971 pHddCtx->last_scan_reject_session_id = curr_session_id;
13972 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053013973 pHddCtx->last_scan_reject_timestamp =
13974 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053013975 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013976 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053013977 else
13978 {
13979 pHddCtx->scan_reject_cnt++;
13980
Abhishek Singh3e500772017-07-17 10:13:43 +053013981 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
13982 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
13983 vos_system_time_after(jiffies_to_msecs(jiffies),
Abhishek Singhe4b12562017-06-20 16:53:39 +053013984 pHddCtx->last_scan_reject_timestamp));
13985
13986 if ((pHddCtx->scan_reject_cnt >=
13987 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053013988 vos_system_time_after(jiffies_to_msecs(jiffies),
13989 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013990 {
13991 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053013992 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013993 if (pHddCtx->cfg_ini->enableFatalEvent)
13994 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
13995 WLAN_LOG_INDICATOR_HOST_DRIVER,
13996 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
13997 FALSE, FALSE);
13998 else
13999 {
14000 hddLog(LOGE, FL("Triggering SSR"));
14001 vos_wlanRestart();
14002 }
14003 }
14004 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014005 return -EBUSY;
14006 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014007 pHddCtx->last_scan_reject_timestamp = 0;
14008 pHddCtx->last_scan_reject_session_id = 0xFF;
14009 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014010 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014011
Jeff Johnson295189b2012-06-20 16:38:30 -070014012 vos_mem_zero( &scanRequest, sizeof(scanRequest));
14013
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014014 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
14015 * Becasue of this, driver is assuming that this is not wildcard scan and so
14016 * is not aging out the scan results.
14017 */
14018 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070014019 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014020 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014021 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014022
14023 if ((request->ssids) && (0 < request->n_ssids))
14024 {
14025 tCsrSSIDInfo *SsidInfo;
14026 int j;
14027 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
14028 /* Allocate num_ssid tCsrSSIDInfo structure */
14029 SsidInfo = scanRequest.SSIDs.SSIDList =
14030 ( tCsrSSIDInfo *)vos_mem_malloc(
14031 request->n_ssids*sizeof(tCsrSSIDInfo));
14032
14033 if(NULL == scanRequest.SSIDs.SSIDList)
14034 {
14035 hddLog(VOS_TRACE_LEVEL_ERROR,
14036 "%s: memory alloc failed SSIDInfo buffer", __func__);
14037 return -ENOMEM;
14038 }
14039
14040 /* copy all the ssid's and their length */
14041 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
14042 {
14043 /* get the ssid length */
14044 SsidInfo->SSID.length = request->ssids[j].ssid_len;
14045 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
14046 SsidInfo->SSID.length);
14047 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
14048 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
14049 j, SsidInfo->SSID.ssId);
14050 }
14051 /* set the scan type to active */
14052 scanRequest.scanType = eSIR_ACTIVE_SCAN;
14053 }
14054 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014055 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014056 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14057 TRACE_CODE_HDD_CFG80211_SCAN,
14058 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070014059 /* set the scan type to active */
14060 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070014061 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014062 else
14063 {
14064 /*Set the scan type to default type, in this case it is ACTIVE*/
14065 scanRequest.scanType = pScanInfo->scan_mode;
14066 }
14067 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
14068 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070014069
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014070 csr_scan_request_assign_bssid(&scanRequest, request);
14071
Jeff Johnson295189b2012-06-20 16:38:30 -070014072 /* set BSSType to default type */
14073 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
14074
14075 /*TODO: scan the requested channels only*/
14076
14077 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014078 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070014079 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014080 hddLog(VOS_TRACE_LEVEL_WARN,
14081 "No of Scan Channels exceeded limit: %d", request->n_channels);
14082 request->n_channels = MAX_CHANNEL;
14083 }
14084
14085 hddLog(VOS_TRACE_LEVEL_INFO,
14086 "No of Scan Channels: %d", request->n_channels);
14087
14088
14089 if( request->n_channels )
14090 {
14091 char chList [(request->n_channels*5)+1];
14092 int len;
14093 channelList = vos_mem_malloc( request->n_channels );
14094 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053014095 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014096 hddLog(VOS_TRACE_LEVEL_ERROR,
14097 "%s: memory alloc failed channelList", __func__);
14098 status = -ENOMEM;
14099 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053014100 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014101
14102 for( i = 0, len = 0; i < request->n_channels ; i++ )
14103 {
14104 channelList[i] = request->channels[i]->hw_value;
14105 len += snprintf(chList+len, 5, "%d ", channelList[i]);
14106 }
14107
Nirav Shah20ac06f2013-12-12 18:14:06 +053014108 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014109 "Channel-List: %s ", chList);
14110 }
c_hpothu53512302014-04-15 18:49:53 +053014111
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014112 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
14113 scanRequest.ChannelInfo.ChannelList = channelList;
14114
14115 /* set requestType to full scan */
14116 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
14117
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014118 /* if there is back to back scan happening in driver with in
14119 * nDeferScanTimeInterval interval driver should defer new scan request
14120 * and should provide last cached scan results instead of new channel list.
14121 * This rule is not applicable if scan is p2p scan.
14122 * This condition will work only in case when last request no of channels
14123 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053014124 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053014125 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014126 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014127
Sushant Kaushik86592172015-04-27 16:35:03 +053014128 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
14129 /* if wps ie is NULL , then only defer scan */
14130 if ( pWpsIe == NULL &&
14131 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053014132 {
14133 if ( pScanInfo->last_scan_timestamp !=0 &&
14134 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
14135 {
14136 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
14137 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
14138 vos_mem_compare(pScanInfo->last_scan_channelList,
14139 channelList, pScanInfo->last_scan_numChannels))
14140 {
14141 hddLog(VOS_TRACE_LEVEL_WARN,
14142 " New and old station scan time differ is less then %u",
14143 pHddCtx->cfg_ini->nDeferScanTimeInterval);
14144
14145 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014146 pAdapter);
14147
Agarwal Ashish57e84372014-12-05 18:26:53 +053014148 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014149 "Return old cached scan as all channels and no of channels are same");
14150
Agarwal Ashish57e84372014-12-05 18:26:53 +053014151 if (0 > ret)
14152 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014153
Agarwal Ashish57e84372014-12-05 18:26:53 +053014154 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014155
14156 status = eHAL_STATUS_SUCCESS;
14157 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053014158 }
14159 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014160 }
14161
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014162 /* Flush the scan results(only p2p beacons) for STA scan and P2P
14163 * search (Flush on both full scan and social scan but not on single
14164 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
14165 */
14166
14167 /* Supplicant does single channel scan after 8-way handshake
14168 * and in that case driver shoudnt flush scan results. If
14169 * driver flushes the scan results here and unfortunately if
14170 * the AP doesnt respond to our probe req then association
14171 * fails which is not desired
14172 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014173 if ((request->n_ssids == 1)
14174 && (request->ssids != NULL)
14175 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
14176 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014177
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014178 if( is_p2p_scan ||
14179 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014180 {
14181 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
14182 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
14183 pAdapter->sessionId );
14184 }
14185
14186 if( request->ie_len )
14187 {
14188 /* save this for future association (join requires this) */
14189 /*TODO: Array needs to be converted to dynamic allocation,
14190 * as multiple ie.s can be sent in cfg80211_scan_request structure
14191 * CR 597966
14192 */
14193 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
14194 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
14195 pScanInfo->scanAddIE.length = request->ie_len;
14196
14197 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14198 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14199 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014200 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014201 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070014202 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014203 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
14204 memcpy( pwextBuf->roamProfile.addIEScan,
14205 request->ie, request->ie_len);
14206 }
14207 else
14208 {
14209 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
14210 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070014211 }
14212
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014213 }
14214 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
14215 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
14216
14217 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
14218 request->ie_len);
14219 if (pP2pIe != NULL)
14220 {
14221#ifdef WLAN_FEATURE_P2P_DEBUG
14222 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
14223 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
14224 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053014225 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014226 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
14227 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14228 "Go nego completed to Connection is started");
14229 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14230 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053014231 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014232 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
14233 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014234 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014235 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
14236 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14237 "Disconnected state to Connection is started");
14238 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14239 "for 4way Handshake");
14240 }
14241#endif
14242
14243 /* no_cck will be set during p2p find to disable 11b rates */
14244 if(TRUE == request->no_cck)
14245 {
14246 hddLog(VOS_TRACE_LEVEL_INFO,
14247 "%s: This is a P2P Search", __func__);
14248 scanRequest.p2pSearch = 1;
14249
14250 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053014251 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014252 /* set requestType to P2P Discovery */
14253 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
14254 }
14255
14256 /*
14257 Skip Dfs Channel in case of P2P Search
14258 if it is set in ini file
14259 */
14260 if(cfg_param->skipDfsChnlInP2pSearch)
14261 {
14262 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014263 }
14264 else
14265 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014266 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014267 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014268
Agarwal Ashish4f616132013-12-30 23:32:50 +053014269 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014270 }
14271 }
14272
14273 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
14274
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014275#ifdef FEATURE_WLAN_TDLS
14276 /* if tdls disagree scan right now, return immediately.
14277 tdls will schedule the scan when scan is allowed. (return SUCCESS)
14278 or will reject the scan if any TDLS is in progress. (return -EBUSY)
14279 */
14280 status = wlan_hdd_tdls_scan_callback (pAdapter,
14281 wiphy,
14282#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14283 dev,
14284#endif
14285 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014286 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014287 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053014288 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014289 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
14290 "scan rejected %d", __func__, status);
14291 else
14292 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
14293 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014294 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053014295 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014296 }
14297#endif
14298
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014299 /* acquire the wakelock to avoid the apps suspend during the scan. To
14300 * address the following issues.
14301 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
14302 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
14303 * for long time, this result in apps running at full power for long time.
14304 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
14305 * be stuck in full power because of resume BMPS
14306 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014307 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014308
Nirav Shah20ac06f2013-12-12 18:14:06 +053014309 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
14310 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014311 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
14312 scanRequest.requestType, scanRequest.scanType,
14313 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053014314 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
14315
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014316 if (pHddCtx->spoofMacAddr.isEnabled &&
14317 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053014318 {
14319 hddLog(VOS_TRACE_LEVEL_INFO,
14320 "%s: MAC Spoofing enabled for current scan", __func__);
14321 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14322 * to fill TxBds for probe request during current scan
14323 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014324 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053014325 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014326
14327 if(status != VOS_STATUS_SUCCESS)
14328 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014329 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014330 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053014331#ifdef FEATURE_WLAN_TDLS
14332 wlan_hdd_tdls_scan_done_callback(pAdapter);
14333#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014334 goto free_mem;
14335 }
Siddharth Bhal76972212014-10-15 16:22:51 +053014336 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014337 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070014338 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014339 pAdapter->sessionId, &scanRequest, &scanId,
14340 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070014341
Jeff Johnson295189b2012-06-20 16:38:30 -070014342 if (eHAL_STATUS_SUCCESS != status)
14343 {
14344 hddLog(VOS_TRACE_LEVEL_ERROR,
14345 "%s: sme_ScanRequest returned error %d", __func__, status);
14346 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014347 if(eHAL_STATUS_RESOURCES == status)
14348 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014349 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
14350 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014351 status = -EBUSY;
14352 } else {
14353 status = -EIO;
14354 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014355 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014356
14357#ifdef FEATURE_WLAN_TDLS
14358 wlan_hdd_tdls_scan_done_callback(pAdapter);
14359#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014360 goto free_mem;
14361 }
14362
14363 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014364 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070014365 pAdapter->request = request;
14366 pScanInfo->scanId = scanId;
14367
14368 complete(&pScanInfo->scan_req_completion_event);
14369
14370free_mem:
14371 if( scanRequest.SSIDs.SSIDList )
14372 {
14373 vos_mem_free(scanRequest.SSIDs.SSIDList);
14374 }
14375
14376 if( channelList )
14377 vos_mem_free( channelList );
14378
14379 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014380 return status;
14381}
14382
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014383int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
14384#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14385 struct net_device *dev,
14386#endif
14387 struct cfg80211_scan_request *request)
14388{
14389 int ret;
14390
14391 vos_ssr_protect(__func__);
14392 ret = __wlan_hdd_cfg80211_scan(wiphy,
14393#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14394 dev,
14395#endif
14396 request);
14397 vos_ssr_unprotect(__func__);
14398
14399 return ret;
14400}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014401
14402void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
14403{
14404 v_U8_t iniDot11Mode =
14405 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
14406 eHddDot11Mode hddDot11Mode = iniDot11Mode;
14407
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014408 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
14409 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014410 switch ( iniDot11Mode )
14411 {
14412 case eHDD_DOT11_MODE_AUTO:
14413 case eHDD_DOT11_MODE_11ac:
14414 case eHDD_DOT11_MODE_11ac_ONLY:
14415#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053014416 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
14417 sme_IsFeatureSupportedByFW(DOT11AC) )
14418 hddDot11Mode = eHDD_DOT11_MODE_11ac;
14419 else
14420 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014421#else
14422 hddDot11Mode = eHDD_DOT11_MODE_11n;
14423#endif
14424 break;
14425 case eHDD_DOT11_MODE_11n:
14426 case eHDD_DOT11_MODE_11n_ONLY:
14427 hddDot11Mode = eHDD_DOT11_MODE_11n;
14428 break;
14429 default:
14430 hddDot11Mode = iniDot11Mode;
14431 break;
14432 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014433#ifdef WLAN_FEATURE_AP_HT40_24G
14434 if (operationChannel > SIR_11B_CHANNEL_END)
14435#endif
14436 {
14437 /* This call decides required channel bonding mode */
14438 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014439 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
14440 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014441 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014442}
14443
Jeff Johnson295189b2012-06-20 16:38:30 -070014444/*
14445 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014446 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014447 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014448int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014449 const u8 *ssid, size_t ssid_len, const u8 *bssid,
14450 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070014451{
14452 int status = 0;
14453 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080014454 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053014455 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014456 v_U32_t roamId;
14457 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070014458 eCsrAuthType RSNAuthType;
14459
14460 ENTER();
14461
14462 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080014463 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053014464 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080014465
14466 status = wlan_hdd_validate_context(pHddCtx);
14467 if (status)
14468 {
Yue Mae36e3552014-03-05 17:06:20 -080014469 return status;
14470 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014471
Jeff Johnson295189b2012-06-20 16:38:30 -070014472 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
14473 {
14474 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
14475 return -EINVAL;
14476 }
14477
Nitesh Shah9b066282017-06-06 18:05:52 +053014478 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
14479
Jeff Johnson295189b2012-06-20 16:38:30 -070014480 pRoamProfile = &pWextState->roamProfile;
14481
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014482 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070014483 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014484 hdd_station_ctx_t *pHddStaCtx;
14485 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053014486 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014487
Siddharth Bhalda0d1622015-04-24 15:47:49 +053014488 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
14489
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014490 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070014491 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
14492 {
14493 /*QoS not enabled in cfg file*/
14494 pRoamProfile->uapsd_mask = 0;
14495 }
14496 else
14497 {
14498 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014499 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070014500 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
14501 }
14502
14503 pRoamProfile->SSIDs.numOfSSIDs = 1;
14504 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
14505 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014506 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070014507 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
14508 ssid, ssid_len);
14509
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014510 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
14511 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
14512
Jeff Johnson295189b2012-06-20 16:38:30 -070014513 if (bssid)
14514 {
14515 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014516 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014517 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014518 /* Save BSSID in seperate variable as well, as RoamProfile
14519 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070014520 case of join failure we should send valid BSSID to supplicant
14521 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014522 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014523 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014524
Jeff Johnson295189b2012-06-20 16:38:30 -070014525 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014526 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070014527 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014528 /* Store bssid_hint to use in the scan filter. */
14529 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
14530 WNI_CFG_BSSID_LEN);
14531 /*
14532 * Save BSSID in seperate variable as well, as RoamProfile
14533 * BSSID is getting zeroed out in the association process. And in
14534 * case of join failure we should send valid BSSID to supplicant
14535 */
14536 vos_mem_copy(pWextState->req_bssId, bssid_hint,
14537 WNI_CFG_BSSID_LEN);
14538 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
14539 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070014540 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014541
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014542
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014543 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
14544 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014545 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
14546 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014547 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014548 /*set gen ie*/
14549 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
14550 /*set auth*/
14551 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
14552 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014553#ifdef FEATURE_WLAN_WAPI
14554 if (pAdapter->wapi_info.nWapiMode)
14555 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014556 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014557 switch (pAdapter->wapi_info.wapiAuthMode)
14558 {
14559 case WAPI_AUTH_MODE_PSK:
14560 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014561 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014562 pAdapter->wapi_info.wapiAuthMode);
14563 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
14564 break;
14565 }
14566 case WAPI_AUTH_MODE_CERT:
14567 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014568 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014569 pAdapter->wapi_info.wapiAuthMode);
14570 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
14571 break;
14572 }
14573 } // End of switch
14574 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
14575 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
14576 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014577 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014578 pRoamProfile->AuthType.numEntries = 1;
14579 pRoamProfile->EncryptionType.numEntries = 1;
14580 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14581 pRoamProfile->mcEncryptionType.numEntries = 1;
14582 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14583 }
14584 }
14585#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014586#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014587 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014588 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14589 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
14590 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014591 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
14592 sizeof (tSirGtkOffloadParams));
14593 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014594 }
14595#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014596 pRoamProfile->csrPersona = pAdapter->device_mode;
14597
Jeff Johnson32d95a32012-09-10 13:15:23 -070014598 if( operatingChannel )
14599 {
14600 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
14601 pRoamProfile->ChannelInfo.numOfChannels = 1;
14602 }
Chet Lanctot186b5732013-03-18 10:26:30 -070014603 else
14604 {
14605 pRoamProfile->ChannelInfo.ChannelList = NULL;
14606 pRoamProfile->ChannelInfo.numOfChannels = 0;
14607 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014608 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
14609 {
14610 hdd_select_cbmode(pAdapter,operatingChannel);
14611 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014612
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014613 /*
14614 * Change conn_state to connecting before sme_RoamConnect(),
14615 * because sme_RoamConnect() has a direct path to call
14616 * hdd_smeRoamCallback(), which will change the conn_state
14617 * If direct path, conn_state will be accordingly changed
14618 * to NotConnected or Associated by either
14619 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
14620 * in sme_RoamCallback()
14621 * if sme_RomConnect is to be queued,
14622 * Connecting state will remain until it is completed.
14623 * If connection state is not changed,
14624 * connection state will remain in eConnectionState_NotConnected state.
14625 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
14626 * if conn state is eConnectionState_NotConnected.
14627 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
14628 * informed of connect result indication which is an issue.
14629 */
14630
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014631 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14632 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053014633 {
14634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014635 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014636 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
14637 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053014638 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014639 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014640 pAdapter->sessionId, pRoamProfile, &roamId);
14641
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014642 if ((eHAL_STATUS_SUCCESS != status) &&
14643 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14644 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014645
14646 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014647 hddLog(VOS_TRACE_LEVEL_ERROR,
14648 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
14649 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014650 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014651 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014652 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014653 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014654
14655 pRoamProfile->ChannelInfo.ChannelList = NULL;
14656 pRoamProfile->ChannelInfo.numOfChannels = 0;
14657
Jeff Johnson295189b2012-06-20 16:38:30 -070014658 }
14659 else
14660 {
14661 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
14662 return -EINVAL;
14663 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080014664 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014665 return status;
14666}
14667
14668/*
14669 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
14670 * This function is used to set the authentication type (OPEN/SHARED).
14671 *
14672 */
14673static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
14674 enum nl80211_auth_type auth_type)
14675{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014676 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014677 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14678
14679 ENTER();
14680
14681 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014682 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070014683 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014684 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014685 hddLog(VOS_TRACE_LEVEL_INFO,
14686 "%s: set authentication type to AUTOSWITCH", __func__);
14687 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
14688 break;
14689
14690 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014691#ifdef WLAN_FEATURE_VOWIFI_11R
14692 case NL80211_AUTHTYPE_FT:
14693#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014694 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014695 "%s: set authentication type to OPEN", __func__);
14696 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
14697 break;
14698
14699 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014700 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014701 "%s: set authentication type to SHARED", __func__);
14702 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
14703 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014704#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014705 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014706 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014707 "%s: set authentication type to CCKM WPA", __func__);
14708 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
14709 break;
14710#endif
14711
14712
14713 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014714 hddLog(VOS_TRACE_LEVEL_ERROR,
14715 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014716 auth_type);
14717 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
14718 return -EINVAL;
14719 }
14720
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014721 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014722 pHddStaCtx->conn_info.authType;
14723 return 0;
14724}
14725
14726/*
14727 * FUNCTION: wlan_hdd_set_akm_suite
14728 * This function is used to set the key mgmt type(PSK/8021x).
14729 *
14730 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014731static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014732 u32 key_mgmt
14733 )
14734{
14735 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14736 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053014737 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014738#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053014739#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014740#endif
14741#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053014742#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014743#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014744 /*set key mgmt type*/
14745 switch(key_mgmt)
14746 {
14747 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053014748 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014749#ifdef WLAN_FEATURE_VOWIFI_11R
14750 case WLAN_AKM_SUITE_FT_PSK:
14751#endif
14752 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070014753 __func__);
14754 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
14755 break;
14756
14757 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053014758 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014759#ifdef WLAN_FEATURE_VOWIFI_11R
14760 case WLAN_AKM_SUITE_FT_8021X:
14761#endif
14762 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070014763 __func__);
14764 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14765 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014766#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014767#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
14768#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
14769 case WLAN_AKM_SUITE_CCKM:
14770 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
14771 __func__);
14772 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
14773 break;
14774#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070014775#ifndef WLAN_AKM_SUITE_OSEN
14776#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
14777 case WLAN_AKM_SUITE_OSEN:
14778 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
14779 __func__);
14780 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14781 break;
14782#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014783
14784 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014785 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014786 __func__, key_mgmt);
14787 return -EINVAL;
14788
14789 }
14790 return 0;
14791}
14792
14793/*
14794 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014795 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070014796 * (NONE/WEP40/WEP104/TKIP/CCMP).
14797 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014798static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
14799 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070014800 bool ucast
14801 )
14802{
14803 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014804 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014805 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14806
14807 ENTER();
14808
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014809 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014810 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014811 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070014812 __func__, cipher);
14813 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14814 }
14815 else
14816 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014817
Jeff Johnson295189b2012-06-20 16:38:30 -070014818 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014819 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014820 {
14821 case IW_AUTH_CIPHER_NONE:
14822 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14823 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014824
Jeff Johnson295189b2012-06-20 16:38:30 -070014825 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014826 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070014827 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014828
Jeff Johnson295189b2012-06-20 16:38:30 -070014829 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014830 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070014831 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014832
Jeff Johnson295189b2012-06-20 16:38:30 -070014833 case WLAN_CIPHER_SUITE_TKIP:
14834 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
14835 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014836
Jeff Johnson295189b2012-06-20 16:38:30 -070014837 case WLAN_CIPHER_SUITE_CCMP:
14838 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14839 break;
14840#ifdef FEATURE_WLAN_WAPI
14841 case WLAN_CIPHER_SUITE_SMS4:
14842 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
14843 break;
14844#endif
14845
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014846#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014847 case WLAN_CIPHER_SUITE_KRK:
14848 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
14849 break;
14850#endif
14851 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014852 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014853 __func__, cipher);
14854 return -EOPNOTSUPP;
14855 }
14856 }
14857
14858 if (ucast)
14859 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014860 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014861 __func__, encryptionType);
14862 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14863 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014864 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014865 encryptionType;
14866 }
14867 else
14868 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014869 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014870 __func__, encryptionType);
14871 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
14872 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
14873 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
14874 }
14875
14876 return 0;
14877}
14878
14879
14880/*
14881 * FUNCTION: wlan_hdd_cfg80211_set_ie
14882 * This function is used to parse WPA/RSN IE's.
14883 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014884int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014885#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14886 const u8 *ie,
14887#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014888 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014889#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014890 size_t ie_len
14891 )
14892{
14893 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014894#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14895 const u8 *genie = ie;
14896#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014897 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014898#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014899 v_U16_t remLen = ie_len;
14900#ifdef FEATURE_WLAN_WAPI
14901 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
14902 u16 *tmp;
14903 v_U16_t akmsuiteCount;
14904 int *akmlist;
14905#endif
14906 ENTER();
14907
14908 /* clear previous assocAddIE */
14909 pWextState->assocAddIE.length = 0;
14910 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014911 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014912
14913 while (remLen >= 2)
14914 {
14915 v_U16_t eLen = 0;
14916 v_U8_t elementId;
14917 elementId = *genie++;
14918 eLen = *genie++;
14919 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014920
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053014921 /* Sanity check on eLen */
14922 if (eLen > remLen) {
14923 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
14924 __func__, eLen, elementId);
14925 VOS_ASSERT(0);
14926 return -EINVAL;
14927 }
14928
Arif Hussain6d2a3322013-11-17 19:50:10 -080014929 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070014930 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014931
14932 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070014933 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014934 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014935 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 -070014936 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014937 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014938 "%s: Invalid WPA IE", __func__);
14939 return -EINVAL;
14940 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014941 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070014942 {
14943 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014944 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014945 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014946
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014947 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014948 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014949 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
14950 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014951 VOS_ASSERT(0);
14952 return -ENOMEM;
14953 }
14954 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14955 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14956 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014957
Jeff Johnson295189b2012-06-20 16:38:30 -070014958 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
14959 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14960 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14961 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014962 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
14963 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053014964 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
14965 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
14966 __func__, eLen);
14967 VOS_ASSERT(0);
14968 return -EINVAL;
14969 }
14970
Jeff Johnson295189b2012-06-20 16:38:30 -070014971 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
14972 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14973 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
14974 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
14975 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
14976 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014977 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053014978 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070014979 {
14980 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014981 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014982 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014983
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014984 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014985 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014986 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14987 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014988 VOS_ASSERT(0);
14989 return -ENOMEM;
14990 }
14991 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14992 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14993 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014994
Jeff Johnson295189b2012-06-20 16:38:30 -070014995 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14996 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14997 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014998#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014999 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
15000 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015001 /*Consider WFD IE, only for P2P Client */
15002 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15003 {
15004 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015005 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015006 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015007
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015008 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015009 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015010 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15011 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015012 VOS_ASSERT(0);
15013 return -ENOMEM;
15014 }
15015 // WFD IE is saved to Additional IE ; it should be accumulated to handle
15016 // WPS IE + P2P IE + WFD IE
15017 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15018 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015019
Jeff Johnson295189b2012-06-20 16:38:30 -070015020 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15021 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15022 }
15023#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015024 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015025 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015026 HS20_OUI_TYPE_SIZE)) )
15027 {
15028 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015029 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015030 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015031
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015032 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015033 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015034 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15035 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015036 VOS_ASSERT(0);
15037 return -ENOMEM;
15038 }
15039 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15040 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015041
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015042 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15043 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15044 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015045 /* Appending OSEN Information Element in Assiciation Request */
15046 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
15047 OSEN_OUI_TYPE_SIZE)) )
15048 {
15049 v_U16_t curAddIELen = pWextState->assocAddIE.length;
15050 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
15051 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015052
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015053 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015054 {
15055 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15056 "Need bigger buffer space");
15057 VOS_ASSERT(0);
15058 return -ENOMEM;
15059 }
15060 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15061 pWextState->assocAddIE.length += eLen + 2;
15062
15063 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
15064 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15065 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15066 }
15067
Abhishek Singh4322e622015-06-10 15:42:54 +053015068 /* Update only for WPA IE */
15069 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
15070 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015071
15072 /* populating as ADDIE in beacon frames */
15073 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015074 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015075 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
15076 {
15077 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15078 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
15079 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15080 {
15081 hddLog(LOGE,
15082 "Coldn't pass "
15083 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
15084 }
15085 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
15086 else
15087 hddLog(LOGE,
15088 "Could not pass on "
15089 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
15090
15091 /* IBSS mode doesn't contain params->proberesp_ies still
15092 beaconIE's need to be populated in probe response frames */
15093 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
15094 {
15095 u16 rem_probe_resp_ie_len = eLen + 2;
15096 u8 probe_rsp_ie_len[3] = {0};
15097 u8 counter = 0;
15098
15099 /* Check Probe Resp Length if it is greater then 255 then
15100 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
15101 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
15102 not able Store More then 255 bytes into One Variable */
15103
15104 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
15105 {
15106 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
15107 {
15108 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
15109 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
15110 }
15111 else
15112 {
15113 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
15114 rem_probe_resp_ie_len = 0;
15115 }
15116 }
15117
15118 rem_probe_resp_ie_len = 0;
15119
15120 if (probe_rsp_ie_len[0] > 0)
15121 {
15122 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15123 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
15124 (tANI_U8*)(genie - 2),
15125 probe_rsp_ie_len[0], NULL,
15126 eANI_BOOLEAN_FALSE)
15127 == eHAL_STATUS_FAILURE)
15128 {
15129 hddLog(LOGE,
15130 "Could not pass"
15131 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
15132 }
15133 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
15134 }
15135
15136 if (probe_rsp_ie_len[1] > 0)
15137 {
15138 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15139 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
15140 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15141 probe_rsp_ie_len[1], NULL,
15142 eANI_BOOLEAN_FALSE)
15143 == eHAL_STATUS_FAILURE)
15144 {
15145 hddLog(LOGE,
15146 "Could not pass"
15147 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
15148 }
15149 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
15150 }
15151
15152 if (probe_rsp_ie_len[2] > 0)
15153 {
15154 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15155 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
15156 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15157 probe_rsp_ie_len[2], NULL,
15158 eANI_BOOLEAN_FALSE)
15159 == eHAL_STATUS_FAILURE)
15160 {
15161 hddLog(LOGE,
15162 "Could not pass"
15163 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
15164 }
15165 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
15166 }
15167
15168 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15169 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
15170 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15171 {
15172 hddLog(LOGE,
15173 "Could not pass"
15174 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
15175 }
15176 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015177 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070015178 break;
15179 case DOT11F_EID_RSN:
15180 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
15181 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15182 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
15183 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
15184 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
15185 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053015186
Abhishek Singhb16f3562016-01-20 11:08:32 +053015187 /* Appending extended capabilities with Interworking or
15188 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053015189 *
15190 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053015191 * interworkingService or bsstransition bit is set to 1.
15192 * Driver is only interested in interworkingService and
15193 * bsstransition capability from supplicant.
15194 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053015195 * required from supplicat, it needs to be handled while
15196 * sending Assoc Req in LIM.
15197 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015198 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015199 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015200 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015201 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015202 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015203
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015204 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015205 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015206 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15207 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015208 VOS_ASSERT(0);
15209 return -ENOMEM;
15210 }
15211 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15212 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015213
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015214 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15215 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15216 break;
15217 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015218#ifdef FEATURE_WLAN_WAPI
15219 case WLAN_EID_WAPI:
15220 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015221 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070015222 pAdapter->wapi_info.nWapiMode);
15223 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015224 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070015225 akmsuiteCount = WPA_GET_LE16(tmp);
15226 tmp = tmp + 1;
15227 akmlist = (int *)(tmp);
15228 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
15229 {
15230 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
15231 }
15232 else
15233 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015234 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070015235 VOS_ASSERT(0);
15236 return -EINVAL;
15237 }
15238
15239 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
15240 {
15241 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015242 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015243 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015244 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015245 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015246 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015247 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015248 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015249 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
15250 }
15251 break;
15252#endif
15253 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015254 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015255 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015256 /* when Unknown IE is received we should break and continue
15257 * to the next IE in the buffer instead we were returning
15258 * so changing this to break */
15259 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015260 }
15261 genie += eLen;
15262 remLen -= eLen;
15263 }
15264 EXIT();
15265 return 0;
15266}
15267
15268/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015269 * FUNCTION: hdd_isWPAIEPresent
15270 * Parse the received IE to find the WPA IE
15271 *
15272 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015273static bool hdd_isWPAIEPresent(
15274#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
15275 const u8 *ie,
15276#else
15277 u8 *ie,
15278#endif
15279 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015280{
15281 v_U8_t eLen = 0;
15282 v_U16_t remLen = ie_len;
15283 v_U8_t elementId = 0;
15284
15285 while (remLen >= 2)
15286 {
15287 elementId = *ie++;
15288 eLen = *ie++;
15289 remLen -= 2;
15290 if (eLen > remLen)
15291 {
15292 hddLog(VOS_TRACE_LEVEL_ERROR,
15293 "%s: IE length is wrong %d", __func__, eLen);
15294 return FALSE;
15295 }
15296 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
15297 {
15298 /* OUI - 0x00 0X50 0XF2
15299 WPA Information Element - 0x01
15300 WPA version - 0x01*/
15301 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
15302 return TRUE;
15303 }
15304 ie += eLen;
15305 remLen -= eLen;
15306 }
15307 return FALSE;
15308}
15309
15310/*
Jeff Johnson295189b2012-06-20 16:38:30 -070015311 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015312 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015313 * parameters during connect operation.
15314 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015315int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015316 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015317 )
Jeff Johnson295189b2012-06-20 16:38:30 -070015318{
15319 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015320 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015321 ENTER();
15322
15323 /*set wpa version*/
15324 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
15325
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015326 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015327 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053015328 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015329 {
15330 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15331 }
15332 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
15333 {
15334 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15335 }
15336 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015337
15338 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015339 pWextState->wpaVersion);
15340
15341 /*set authentication type*/
15342 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
15343
15344 if (0 > status)
15345 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015346 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015347 "%s: failed to set authentication type ", __func__);
15348 return status;
15349 }
15350
15351 /*set key mgmt type*/
15352 if (req->crypto.n_akm_suites)
15353 {
15354 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
15355 if (0 > status)
15356 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015357 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070015358 __func__);
15359 return status;
15360 }
15361 }
15362
15363 /*set pairwise cipher type*/
15364 if (req->crypto.n_ciphers_pairwise)
15365 {
15366 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
15367 req->crypto.ciphers_pairwise[0], true);
15368 if (0 > status)
15369 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015370 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015371 "%s: failed to set unicast cipher type", __func__);
15372 return status;
15373 }
15374 }
15375 else
15376 {
15377 /*Reset previous cipher suite to none*/
15378 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
15379 if (0 > status)
15380 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015381 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015382 "%s: failed to set unicast cipher type", __func__);
15383 return status;
15384 }
15385 }
15386
15387 /*set group cipher type*/
15388 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
15389 false);
15390
15391 if (0 > status)
15392 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015393 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070015394 __func__);
15395 return status;
15396 }
15397
Chet Lanctot186b5732013-03-18 10:26:30 -070015398#ifdef WLAN_FEATURE_11W
15399 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
15400#endif
15401
Jeff Johnson295189b2012-06-20 16:38:30 -070015402 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
15403 if (req->ie_len)
15404 {
15405 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
15406 if ( 0 > status)
15407 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015408 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015409 __func__);
15410 return status;
15411 }
15412 }
15413
15414 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015415 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015416 {
15417 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
15418 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
15419 )
15420 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015421 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070015422 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
15423 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015424 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015425 __func__);
15426 return -EOPNOTSUPP;
15427 }
15428 else
15429 {
15430 u8 key_len = req->key_len;
15431 u8 key_idx = req->key_idx;
15432
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015433 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015434 && (CSR_MAX_NUM_KEY > key_idx)
15435 )
15436 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015437 hddLog(VOS_TRACE_LEVEL_INFO,
15438 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015439 __func__, key_idx, key_len);
15440 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015441 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070015442 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015443 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015444 (u8)key_len;
15445 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
15446 }
15447 }
15448 }
15449 }
15450
15451 return status;
15452}
15453
15454/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015455 * FUNCTION: wlan_hdd_try_disconnect
15456 * This function is used to disconnect from previous
15457 * connection
15458 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053015459int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015460{
15461 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015462 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015463 hdd_station_ctx_t *pHddStaCtx;
15464 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015465 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015466
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015467 ret = wlan_hdd_validate_context(pHddCtx);
15468 if (0 != ret)
15469 {
15470 return ret;
15471 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015472 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15473
15474 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
15475
15476 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
15477 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053015478 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015479 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
15480 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053015481 /* Indicate disconnect to SME so that in-progress connection or preauth
15482 * can be aborted
15483 */
15484 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
15485 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015486 spin_lock_bh(&pAdapter->lock_for_active_session);
15487 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15488 {
15489 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15490 }
15491 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053015492 hdd_connSetConnectionState(pHddStaCtx,
15493 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015494 /* Issue disconnect to CSR */
15495 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015496 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015497 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015498 eCSR_DISCONNECT_REASON_UNSPECIFIED);
15499 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
15500 hddLog(LOG1,
15501 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
15502 } else if ( 0 != status ) {
15503 hddLog(LOGE,
15504 FL("csrRoamDisconnect failure, returned %d"),
15505 (int)status );
15506 result = -EINVAL;
15507 goto disconnected;
15508 }
15509 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015510 &pAdapter->disconnect_comp_var,
15511 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015512 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
15513 hddLog(LOGE,
15514 "%s: Failed to disconnect, timed out", __func__);
15515 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015516 }
15517 }
15518 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
15519 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015520 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015521 &pAdapter->disconnect_comp_var,
15522 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015523 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015524 {
15525 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015526 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015527 }
15528 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015529disconnected:
15530 hddLog(LOG1,
15531 FL("Set HDD connState to eConnectionState_NotConnected"));
15532 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
15533 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015534}
15535
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015536/**
15537 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
15538 * @adapter: Pointer to the HDD adapter
15539 * @req: Pointer to the structure cfg_connect_params receieved from user space
15540 *
15541 * This function will start reassociation if bssid hint, channel hint and
15542 * previous bssid parameters are present in the connect request
15543 *
15544 * Return: success if reassociation is happening
15545 * Error code if reassociation is not permitted or not happening
15546 */
15547#ifdef CFG80211_CONNECT_PREV_BSSID
15548static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15549 struct cfg80211_connect_params *req)
15550{
15551 int status = -EPERM;
15552 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
15553 hddLog(VOS_TRACE_LEVEL_INFO,
15554 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
15555 req->channel_hint->hw_value,
15556 MAC_ADDR_ARRAY(req->bssid_hint));
15557 status = hdd_reassoc(adapter, req->bssid_hint,
15558 req->channel_hint->hw_value,
15559 CONNECT_CMD_USERSPACE);
15560 }
15561 return status;
15562}
15563#else
15564static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15565 struct cfg80211_connect_params *req)
15566{
15567 return -EPERM;
15568}
15569#endif
15570
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015571/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053015572 * FUNCTION: __wlan_hdd_cfg80211_connect
15573 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015574 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015575static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015576 struct net_device *ndev,
15577 struct cfg80211_connect_params *req
15578 )
15579{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015580 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015581 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053015582#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
15583 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015584 const u8 *bssid_hint = req->bssid_hint;
15585#else
15586 const u8 *bssid_hint = NULL;
15587#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015588 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015589 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053015590 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015591
15592 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015593
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015594 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15595 TRACE_CODE_HDD_CFG80211_CONNECT,
15596 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015597 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015598 "%s: device_mode = %s (%d)", __func__,
15599 hdd_device_modetoString(pAdapter->device_mode),
15600 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015601
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015602 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015603 if (!pHddCtx)
15604 {
15605 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15606 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015607 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015608 }
15609
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015610 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015611 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015612 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015613 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015614 }
15615
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015616 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
15617 if (0 == status)
15618 return status;
15619
Agarwal Ashish51325b52014-06-16 16:50:49 +053015620
Jeff Johnson295189b2012-06-20 16:38:30 -070015621#ifdef WLAN_BTAMP_FEATURE
15622 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015623 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070015624 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015625 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015626 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080015627 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070015628 }
15629#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015630
15631 //If Device Mode is Station Concurrent Sessions Exit BMps
15632 //P2P Mode will be taken care in Open/close adapter
15633 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053015634 (vos_concurrent_open_sessions_running())) {
15635 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
15636 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015637 }
15638
15639 /*Try disconnecting if already in connected state*/
15640 status = wlan_hdd_try_disconnect(pAdapter);
15641 if ( 0 > status)
15642 {
15643 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15644 " connection"));
15645 return -EALREADY;
15646 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053015647 /* Check for max concurrent connections after doing disconnect if any*/
15648 if (vos_max_concurrent_connections_reached()) {
15649 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15650 return -ECONNREFUSED;
15651 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015652
Jeff Johnson295189b2012-06-20 16:38:30 -070015653 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015654 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070015655
15656 if ( 0 > status)
15657 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015658 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070015659 __func__);
15660 return status;
15661 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053015662
15663 if (pHddCtx->spoofMacAddr.isEnabled)
15664 {
15665 hddLog(VOS_TRACE_LEVEL_INFO,
15666 "%s: MAC Spoofing enabled ", __func__);
15667 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15668 * to fill TxBds for probe request during SSID scan which may happen
15669 * as part of connect command
15670 */
15671 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
15672 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
15673 if (status != VOS_STATUS_SUCCESS)
15674 return -ECONNREFUSED;
15675 }
15676
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015677 if (req->channel)
15678 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070015679 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015680 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053015681
15682 /* Abort if any scan is going on */
15683 status = wlan_hdd_scan_abort(pAdapter);
15684 if (0 != status)
15685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
15686
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015687 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
15688 req->ssid_len, req->bssid,
15689 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015690
Sushant Kaushikd7083982015-03-18 14:33:24 +053015691 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015692 {
15693 //ReEnable BMPS if disabled
15694 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
15695 (NULL != pHddCtx))
15696 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053015697 if (pHddCtx->hdd_wlan_suspended)
15698 {
15699 hdd_set_pwrparams(pHddCtx);
15700 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015701 //ReEnable Bmps and Imps back
15702 hdd_enable_bmps_imps(pHddCtx);
15703 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015704 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070015705 return status;
15706 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015707 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015708 EXIT();
15709 return status;
15710}
15711
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015712static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
15713 struct net_device *ndev,
15714 struct cfg80211_connect_params *req)
15715{
15716 int ret;
15717 vos_ssr_protect(__func__);
15718 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
15719 vos_ssr_unprotect(__func__);
15720
15721 return ret;
15722}
Jeff Johnson295189b2012-06-20 16:38:30 -070015723
15724/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015725 * FUNCTION: wlan_hdd_disconnect
15726 * This function is used to issue a disconnect request to SME
15727 */
15728int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
15729{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015730 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015731 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015732 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015733 long ret;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015734 eConnectionState prev_conn_state;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015735
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015736 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015737
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015738 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015739 if (0 != status)
15740 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015741 return status;
15742 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053015743 /* Indicate sme of disconnect so that in progress connection or preauth
15744 * can be aborted
15745 */
15746 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053015747 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015748 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015749
Agarwal Ashish47d18112014-08-04 19:55:07 +053015750 /* Need to apply spin lock before decreasing active sessions
15751 * as there can be chance for double decrement if context switch
15752 * Calls hdd_DisConnectHandler.
15753 */
15754
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015755 prev_conn_state = pHddStaCtx->conn_info.connState;
15756
Agarwal Ashish47d18112014-08-04 19:55:07 +053015757 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015758 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15759 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015760 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15761 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053015762 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
15763 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015764
Abhishek Singhf4669da2014-05-26 15:07:49 +053015765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053015766 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
15767
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015768 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015769
Mihir Shete182a0b22014-08-18 16:08:48 +053015770 /*
15771 * stop tx queues before deleting STA/BSS context from the firmware.
15772 * tx has to be disabled because the firmware can get busy dropping
15773 * the tx frames after BSS/STA has been deleted and will not send
15774 * back a response resulting in WDI timeout
15775 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053015776 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053015777 netif_tx_disable(pAdapter->dev);
15778 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015779
Mihir Shete182a0b22014-08-18 16:08:48 +053015780 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015781 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
15782 pAdapter->sessionId, reason);
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015783 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
15784 prev_conn_state != eConnectionState_Connecting)
15785 {
15786 hddLog(LOG1,
15787 FL("status = %d, already disconnected"), status);
15788 result = 0;
15789 goto disconnected;
15790 }
15791 /*
15792 * Wait here instead of returning directly, this will block the next
15793 * connect command and allow processing of the scan for ssid and
15794 * the previous connect command in CSR. Else we might hit some
15795 * race conditions leading to SME and HDD out of sync.
15796 */
15797 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015798 {
15799 hddLog(LOG1,
15800 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015801 }
15802 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015803 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015804 hddLog(LOGE,
15805 FL("csrRoamDisconnect failure, returned %d"),
15806 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015807 result = -EINVAL;
15808 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015809 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015810 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015811 &pAdapter->disconnect_comp_var,
15812 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015813 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015814 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015815 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015816 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015817 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015818 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015819disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015820 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015821 FL("Set HDD connState to eConnectionState_NotConnected"));
15822 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015823#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
15824 /* Sending disconnect event to userspace for kernel version < 3.11
15825 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
15826 */
15827 hddLog(LOG1, FL("Send disconnected event to userspace"));
15828
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053015829 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015830 WLAN_REASON_UNSPECIFIED);
15831#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015832
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015833 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015834 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015835}
15836
15837
15838/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015839 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070015840 * This function is used to issue a disconnect request to SME
15841 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015842static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015843 struct net_device *dev,
15844 u16 reason
15845 )
15846{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015847 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015848 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015849 tCsrRoamProfile *pRoamProfile;
15850 hdd_station_ctx_t *pHddStaCtx;
15851 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015852#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015853 tANI_U8 staIdx;
15854#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015855
Jeff Johnson295189b2012-06-20 16:38:30 -070015856 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015857
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015858 if (!pAdapter) {
15859 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15860 return -EINVAL;
15861 }
15862
15863 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15864 if (!pHddStaCtx) {
15865 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
15866 return -EINVAL;
15867 }
15868
15869 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15870 status = wlan_hdd_validate_context(pHddCtx);
15871 if (0 != status)
15872 {
15873 return status;
15874 }
15875
15876 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
15877
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015878 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15879 TRACE_CODE_HDD_CFG80211_DISCONNECT,
15880 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015881 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
15882 __func__, hdd_device_modetoString(pAdapter->device_mode),
15883 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015884
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015885 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
15886 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070015887
Jeff Johnson295189b2012-06-20 16:38:30 -070015888 if (NULL != pRoamProfile)
15889 {
15890 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015891 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
15892 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070015893 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015894 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070015895 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015896 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070015897 switch(reason)
15898 {
15899 case WLAN_REASON_MIC_FAILURE:
15900 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
15901 break;
15902
15903 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
15904 case WLAN_REASON_DISASSOC_AP_BUSY:
15905 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
15906 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
15907 break;
15908
15909 case WLAN_REASON_PREV_AUTH_NOT_VALID:
15910 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053015911 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070015912 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
15913 break;
15914
Jeff Johnson295189b2012-06-20 16:38:30 -070015915 default:
15916 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
15917 break;
15918 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015919 pScanInfo = &pHddCtx->scan_info;
15920 if (pScanInfo->mScanPending)
15921 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015922 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015923 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015924 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015925 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015926 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053015927 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015928#ifdef FEATURE_WLAN_TDLS
15929 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015930 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015931 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015932 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
15933 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015934 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015935 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015936 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015937 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015938 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015939 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015940 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015941 status = sme_DeleteTdlsPeerSta(
15942 WLAN_HDD_GET_HAL_CTX(pAdapter),
15943 pAdapter->sessionId,
15944 mac);
15945 if (status != eHAL_STATUS_SUCCESS) {
15946 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15947 return -EPERM;
15948 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015949 }
15950 }
15951#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015952
15953 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
15954 reasonCode,
15955 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015956 status = wlan_hdd_disconnect(pAdapter, reasonCode);
15957 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070015958 {
15959 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015960 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015961 __func__, (int)status );
15962 return -EINVAL;
15963 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015964 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015965 else
15966 {
15967 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
15968 "called while in %d state", __func__,
15969 pHddStaCtx->conn_info.connState);
15970 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015971 }
15972 else
15973 {
15974 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
15975 }
15976
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015977 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015978 return status;
15979}
15980
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015981static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
15982 struct net_device *dev,
15983 u16 reason
15984 )
15985{
15986 int ret;
15987 vos_ssr_protect(__func__);
15988 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
15989 vos_ssr_unprotect(__func__);
15990
15991 return ret;
15992}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015993
Jeff Johnson295189b2012-06-20 16:38:30 -070015994/*
15995 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015996 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015997 * settings in IBSS mode.
15998 */
15999static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016000 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016001 struct cfg80211_ibss_params *params
16002 )
16003{
16004 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016005 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016006 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16007 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016008
Jeff Johnson295189b2012-06-20 16:38:30 -070016009 ENTER();
16010
16011 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070016012 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070016013
16014 if (params->ie_len && ( NULL != params->ie) )
16015 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016016 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16017 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016018 {
16019 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16020 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16021 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016022 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016023 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016024 tDot11fIEWPA dot11WPAIE;
16025 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016026 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016027
Wilson Yang00256342013-10-10 23:13:38 -070016028 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016029 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16030 params->ie_len, DOT11F_EID_WPA);
16031 if ( NULL != ie )
16032 {
16033 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16034 // Unpack the WPA IE
16035 //Skip past the EID byte and length byte - and four byte WiFi OUI
16036 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
16037 &ie[2+4],
16038 ie[1] - 4,
16039 &dot11WPAIE);
16040 /*Extract the multicast cipher, the encType for unicast
16041 cipher for wpa-none is none*/
16042 encryptionType =
16043 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
16044 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016045 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016046
Jeff Johnson295189b2012-06-20 16:38:30 -070016047 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
16048
16049 if (0 > status)
16050 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016051 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016052 __func__);
16053 return status;
16054 }
16055 }
16056
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016057 pWextState->roamProfile.AuthType.authType[0] =
16058 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070016059 eCSR_AUTH_TYPE_OPEN_SYSTEM;
16060
16061 if (params->privacy)
16062 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016063 /* Security enabled IBSS, At this time there is no information available
16064 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070016065 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016066 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070016067 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016068 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070016069 *enable privacy bit in beacons */
16070
16071 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
16072 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016073 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
16074 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070016075 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16076 pWextState->roamProfile.EncryptionType.numEntries = 1;
16077 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070016078 return status;
16079}
16080
16081/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016082 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016083 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016084 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016085static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016086 struct net_device *dev,
16087 struct cfg80211_ibss_params *params
16088 )
16089{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016090 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016091 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16092 tCsrRoamProfile *pRoamProfile;
16093 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016094 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16095 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016096 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070016097
16098 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016099
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016100 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16101 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
16102 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016103 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016104 "%s: device_mode = %s (%d)", __func__,
16105 hdd_device_modetoString(pAdapter->device_mode),
16106 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016107
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016108 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016109 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016110 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016111 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016112 }
16113
16114 if (NULL == pWextState)
16115 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016116 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016117 __func__);
16118 return -EIO;
16119 }
16120
Agarwal Ashish51325b52014-06-16 16:50:49 +053016121 if (vos_max_concurrent_connections_reached()) {
16122 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16123 return -ECONNREFUSED;
16124 }
16125
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016126 /*Try disconnecting if already in connected state*/
16127 status = wlan_hdd_try_disconnect(pAdapter);
16128 if ( 0 > status)
16129 {
16130 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16131 " IBSS connection"));
16132 return -EALREADY;
16133 }
16134
Jeff Johnson295189b2012-06-20 16:38:30 -070016135 pRoamProfile = &pWextState->roamProfile;
16136
16137 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
16138 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016139 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016140 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016141 return -EINVAL;
16142 }
16143
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016144 /* BSSID is provided by upper layers hence no need to AUTO generate */
16145 if (NULL != params->bssid) {
16146 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16147 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
16148 hddLog (VOS_TRACE_LEVEL_ERROR,
16149 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16150 return -EIO;
16151 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016152 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016153 }
krunal sonie9002db2013-11-25 14:24:17 -080016154 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
16155 {
16156 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16157 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
16158 {
16159 hddLog (VOS_TRACE_LEVEL_ERROR,
16160 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16161 return -EIO;
16162 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016163
16164 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080016165 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016166 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080016167 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016168
Jeff Johnson295189b2012-06-20 16:38:30 -070016169 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070016170 if (NULL !=
16171#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16172 params->chandef.chan)
16173#else
16174 params->channel)
16175#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016176 {
16177 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016178 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16179 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
16180 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16181 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016182
16183 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016184 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070016185 ieee80211_frequency_to_channel(
16186#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16187 params->chandef.chan->center_freq);
16188#else
16189 params->channel->center_freq);
16190#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016191
16192 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16193 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070016194 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016195 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
16196 __func__);
16197 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070016198 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016199
16200 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016201 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016202 if (channelNum == validChan[indx])
16203 {
16204 break;
16205 }
16206 }
16207 if (indx >= numChans)
16208 {
16209 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016210 __func__, channelNum);
16211 return -EINVAL;
16212 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016213 /* Set the Operational Channel */
16214 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
16215 channelNum);
16216 pRoamProfile->ChannelInfo.numOfChannels = 1;
16217 pHddStaCtx->conn_info.operationChannel = channelNum;
16218 pRoamProfile->ChannelInfo.ChannelList =
16219 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070016220 }
16221
16222 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016223 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070016224 if (status < 0)
16225 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016226 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070016227 __func__);
16228 return status;
16229 }
16230
16231 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016232 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053016233 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016234 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016235
16236 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016237 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016238
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016239 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016240 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016241}
16242
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016243static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
16244 struct net_device *dev,
16245 struct cfg80211_ibss_params *params
16246 )
16247{
16248 int ret = 0;
16249
16250 vos_ssr_protect(__func__);
16251 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
16252 vos_ssr_unprotect(__func__);
16253
16254 return ret;
16255}
16256
Jeff Johnson295189b2012-06-20 16:38:30 -070016257/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016258 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016259 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016260 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016261static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016262 struct net_device *dev
16263 )
16264{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016265 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016266 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16267 tCsrRoamProfile *pRoamProfile;
16268 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016269 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053016270 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016271#ifdef WLAN_FEATURE_RMC
16272 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
16273#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016274
16275 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016276
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016277 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16278 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
16279 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016280 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016281 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016282 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016283 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016284 }
16285
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016286 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
16287 hdd_device_modetoString(pAdapter->device_mode),
16288 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016289 if (NULL == pWextState)
16290 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016291 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016292 __func__);
16293 return -EIO;
16294 }
16295
16296 pRoamProfile = &pWextState->roamProfile;
16297
16298 /* Issue disconnect only if interface type is set to IBSS */
16299 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
16300 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016301 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070016302 __func__);
16303 return -EINVAL;
16304 }
16305
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016306#ifdef WLAN_FEATURE_RMC
16307 /* Clearing add IE of beacon */
16308 if (ccmCfgSetStr(pHddCtx->hHal,
16309 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
16310 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
16311 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16312 {
16313 hddLog (VOS_TRACE_LEVEL_ERROR,
16314 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
16315 return -EINVAL;
16316 }
16317 if (ccmCfgSetInt(pHddCtx->hHal,
16318 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
16319 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16320 {
16321 hddLog (VOS_TRACE_LEVEL_ERROR,
16322 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
16323 __func__);
16324 return -EINVAL;
16325 }
16326
16327 // Reset WNI_CFG_PROBE_RSP Flags
16328 wlan_hdd_reset_prob_rspies(pAdapter);
16329
16330 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16331 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
16332 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16333 {
16334 hddLog (VOS_TRACE_LEVEL_ERROR,
16335 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
16336 __func__);
16337 return -EINVAL;
16338 }
16339#endif
16340
Jeff Johnson295189b2012-06-20 16:38:30 -070016341 /* Issue Disconnect request */
16342 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053016343 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
16344 pAdapter->sessionId,
16345 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
16346 if (!HAL_STATUS_SUCCESS(hal_status)) {
16347 hddLog(LOGE,
16348 FL("sme_RoamDisconnect failed hal_status(%d)"),
16349 hal_status);
16350 return -EAGAIN;
16351 }
16352 status = wait_for_completion_timeout(
16353 &pAdapter->disconnect_comp_var,
16354 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
16355 if (!status) {
16356 hddLog(LOGE,
16357 FL("wait on disconnect_comp_var failed"));
16358 return -ETIMEDOUT;
16359 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016360
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016361 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016362 return 0;
16363}
16364
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016365static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
16366 struct net_device *dev
16367 )
16368{
16369 int ret = 0;
16370
16371 vos_ssr_protect(__func__);
16372 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
16373 vos_ssr_unprotect(__func__);
16374
16375 return ret;
16376}
16377
Jeff Johnson295189b2012-06-20 16:38:30 -070016378/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016379 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070016380 * This function is used to set the phy parameters
16381 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
16382 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016383static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016384 u32 changed)
16385{
16386 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16387 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016388 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016389
16390 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016391
16392 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016393 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
16394 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016395
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016396 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016397 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016398 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016399 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016400 }
16401
Jeff Johnson295189b2012-06-20 16:38:30 -070016402 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
16403 {
16404 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
16405 WNI_CFG_RTS_THRESHOLD_STAMAX :
16406 wiphy->rts_threshold;
16407
16408 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016409 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070016410 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016411 hddLog(VOS_TRACE_LEVEL_ERROR,
16412 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016413 __func__, rts_threshold);
16414 return -EINVAL;
16415 }
16416
16417 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
16418 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016419 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016420 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016421 hddLog(VOS_TRACE_LEVEL_ERROR,
16422 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016423 __func__, rts_threshold);
16424 return -EIO;
16425 }
16426
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016427 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016428 rts_threshold);
16429 }
16430
16431 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
16432 {
16433 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
16434 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
16435 wiphy->frag_threshold;
16436
16437 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016438 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016439 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016440 hddLog(VOS_TRACE_LEVEL_ERROR,
16441 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016442 frag_threshold);
16443 return -EINVAL;
16444 }
16445
16446 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
16447 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016448 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016449 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016450 hddLog(VOS_TRACE_LEVEL_ERROR,
16451 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016452 __func__, frag_threshold);
16453 return -EIO;
16454 }
16455
16456 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
16457 frag_threshold);
16458 }
16459
16460 if ((changed & WIPHY_PARAM_RETRY_SHORT)
16461 || (changed & WIPHY_PARAM_RETRY_LONG))
16462 {
16463 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
16464 wiphy->retry_short :
16465 wiphy->retry_long;
16466
16467 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
16468 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
16469 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016470 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016471 __func__, retry_value);
16472 return -EINVAL;
16473 }
16474
16475 if (changed & WIPHY_PARAM_RETRY_SHORT)
16476 {
16477 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
16478 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016479 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016480 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016481 hddLog(VOS_TRACE_LEVEL_ERROR,
16482 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016483 __func__, retry_value);
16484 return -EIO;
16485 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016486 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016487 __func__, retry_value);
16488 }
16489 else if (changed & WIPHY_PARAM_RETRY_SHORT)
16490 {
16491 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
16492 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016493 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016494 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016495 hddLog(VOS_TRACE_LEVEL_ERROR,
16496 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016497 __func__, retry_value);
16498 return -EIO;
16499 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016500 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016501 __func__, retry_value);
16502 }
16503 }
16504
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016505 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016506 return 0;
16507}
16508
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016509static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
16510 u32 changed)
16511{
16512 int ret;
16513
16514 vos_ssr_protect(__func__);
16515 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
16516 vos_ssr_unprotect(__func__);
16517
16518 return ret;
16519}
16520
Jeff Johnson295189b2012-06-20 16:38:30 -070016521/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016522 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070016523 * This function is used to set the txpower
16524 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016525static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070016526#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16527 struct wireless_dev *wdev,
16528#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016529#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016530 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070016531#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016532 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070016533#endif
16534 int dbm)
16535{
16536 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016537 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016538 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
16539 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016540 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016541
16542 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016543
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016544 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16545 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
16546 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016547 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016548 if (0 != status)
16549 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016550 return status;
16551 }
16552
16553 hHal = pHddCtx->hHal;
16554
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016555 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
16556 dbm, ccmCfgSetCallback,
16557 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016558 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016559 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016560 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
16561 return -EIO;
16562 }
16563
16564 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
16565 dbm);
16566
16567 switch(type)
16568 {
16569 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
16570 /* Fall through */
16571 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
16572 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
16573 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016574 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
16575 __func__);
16576 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070016577 }
16578 break;
16579 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016580 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016581 __func__);
16582 return -EOPNOTSUPP;
16583 break;
16584 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016585 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
16586 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070016587 return -EIO;
16588 }
16589
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016590 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016591 return 0;
16592}
16593
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016594static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
16595#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16596 struct wireless_dev *wdev,
16597#endif
16598#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16599 enum tx_power_setting type,
16600#else
16601 enum nl80211_tx_power_setting type,
16602#endif
16603 int dbm)
16604{
16605 int ret;
16606 vos_ssr_protect(__func__);
16607 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
16608#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16609 wdev,
16610#endif
16611#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16612 type,
16613#else
16614 type,
16615#endif
16616 dbm);
16617 vos_ssr_unprotect(__func__);
16618
16619 return ret;
16620}
16621
Jeff Johnson295189b2012-06-20 16:38:30 -070016622/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016623 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070016624 * This function is used to read the txpower
16625 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016626static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070016627#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16628 struct wireless_dev *wdev,
16629#endif
16630 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070016631{
16632
16633 hdd_adapter_t *pAdapter;
16634 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016635 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016636
Jeff Johnsone7245742012-09-05 17:12:55 -070016637 ENTER();
16638
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016639 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016640 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016641 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016642 *dbm = 0;
16643 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016644 }
16645
Jeff Johnson295189b2012-06-20 16:38:30 -070016646 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
16647 if (NULL == pAdapter)
16648 {
16649 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
16650 return -ENOENT;
16651 }
16652
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016653 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16654 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
16655 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070016656 wlan_hdd_get_classAstats(pAdapter);
16657 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
16658
Jeff Johnsone7245742012-09-05 17:12:55 -070016659 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016660 return 0;
16661}
16662
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016663static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
16664#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16665 struct wireless_dev *wdev,
16666#endif
16667 int *dbm)
16668{
16669 int ret;
16670
16671 vos_ssr_protect(__func__);
16672 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
16673#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16674 wdev,
16675#endif
16676 dbm);
16677 vos_ssr_unprotect(__func__);
16678
16679 return ret;
16680}
16681
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016682static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016683#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16684 const u8* mac,
16685#else
16686 u8* mac,
16687#endif
16688 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070016689{
16690 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
16691 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16692 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053016693 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016694
16695 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
16696 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070016697
16698 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
16699 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
16700 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
16701 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
16702 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
16703 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
16704 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053016705 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070016706 tANI_U16 myRate;
16707 tANI_U16 currentRate = 0;
16708 tANI_U8 maxSpeedMCS = 0;
16709 tANI_U8 maxMCSIdx = 0;
16710 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053016711 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070016712 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016713 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016714
Leo Chang6f8870f2013-03-26 18:11:36 -070016715#ifdef WLAN_FEATURE_11AC
16716 tANI_U32 vht_mcs_map;
16717 eDataRate11ACMaxMcs vhtMaxMcs;
16718#endif /* WLAN_FEATURE_11AC */
16719
Jeff Johnsone7245742012-09-05 17:12:55 -070016720 ENTER();
16721
Jeff Johnson295189b2012-06-20 16:38:30 -070016722 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
16723 (0 == ssidlen))
16724 {
16725 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
16726 " Invalid ssidlen, %d", __func__, ssidlen);
16727 /*To keep GUI happy*/
16728 return 0;
16729 }
16730
Mukul Sharma811205f2014-07-09 21:07:30 +053016731 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16732 {
16733 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16734 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053016735 /* return a cached value */
16736 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053016737 return 0;
16738 }
16739
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016740 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016741 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016742 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016743 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016744 }
16745
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053016746 wlan_hdd_get_station_stats(pAdapter);
16747 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016748
Kiet Lam3b17fc82013-09-27 05:24:08 +053016749 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053016750 wlan_hdd_get_snr(pAdapter, &snr);
16751 pHddStaCtx->conn_info.signal = sinfo->signal;
16752 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Kiet Lam3b17fc82013-09-27 05:24:08 +053016753 sinfo->filled |= STATION_INFO_SIGNAL;
16754
c_hpothu09f19542014-05-30 21:53:31 +053016755 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053016756 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
16757 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053016758 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053016759 {
16760 rate_flags = pAdapter->maxRateFlags;
16761 }
c_hpothu44ff4e02014-05-08 00:13:57 +053016762
Jeff Johnson295189b2012-06-20 16:38:30 -070016763 //convert to the UI units of 100kbps
16764 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
16765
16766#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070016767 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 -070016768 sinfo->signal,
16769 pCfg->reportMaxLinkSpeed,
16770 myRate,
16771 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016772 (int) pCfg->linkSpeedRssiMid,
16773 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070016774 (int) rate_flags,
16775 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070016776#endif //LINKSPEED_DEBUG_ENABLED
16777
16778 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
16779 {
16780 // we do not want to necessarily report the current speed
16781 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
16782 {
16783 // report the max possible speed
16784 rssidx = 0;
16785 }
16786 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
16787 {
16788 // report the max possible speed with RSSI scaling
16789 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
16790 {
16791 // report the max possible speed
16792 rssidx = 0;
16793 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016794 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070016795 {
16796 // report middle speed
16797 rssidx = 1;
16798 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016799 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
16800 {
16801 // report middle speed
16802 rssidx = 2;
16803 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016804 else
16805 {
16806 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016807 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070016808 }
16809 }
16810 else
16811 {
16812 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
16813 hddLog(VOS_TRACE_LEVEL_ERROR,
16814 "%s: Invalid value for reportMaxLinkSpeed: %u",
16815 __func__, pCfg->reportMaxLinkSpeed);
16816 rssidx = 0;
16817 }
16818
16819 maxRate = 0;
16820
16821 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016822 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
16823 OperationalRates, &ORLeng))
16824 {
16825 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16826 /*To keep GUI happy*/
16827 return 0;
16828 }
16829
Jeff Johnson295189b2012-06-20 16:38:30 -070016830 for (i = 0; i < ORLeng; i++)
16831 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016832 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016833 {
16834 /* Validate Rate Set */
16835 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
16836 {
16837 currentRate = supported_data_rate[j].supported_rate[rssidx];
16838 break;
16839 }
16840 }
16841 /* Update MAX rate */
16842 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16843 }
16844
16845 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016846 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
16847 ExtendedRates, &ERLeng))
16848 {
16849 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16850 /*To keep GUI happy*/
16851 return 0;
16852 }
16853
Jeff Johnson295189b2012-06-20 16:38:30 -070016854 for (i = 0; i < ERLeng; i++)
16855 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016856 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016857 {
16858 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
16859 {
16860 currentRate = supported_data_rate[j].supported_rate[rssidx];
16861 break;
16862 }
16863 }
16864 /* Update MAX rate */
16865 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16866 }
c_hpothu79aab322014-07-14 21:11:01 +053016867
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016868 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053016869 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016870 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053016871 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070016872 {
c_hpothu79aab322014-07-14 21:11:01 +053016873 if (rate_flags & eHAL_TX_RATE_VHT80)
16874 mode = 2;
16875 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
16876 mode = 1;
16877 else
16878 mode = 0;
16879
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016880 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
16881 MCSRates, &MCSLeng))
16882 {
16883 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16884 /*To keep GUI happy*/
16885 return 0;
16886 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016887 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070016888#ifdef WLAN_FEATURE_11AC
16889 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016890 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070016891 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016892 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016893 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070016894 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070016895 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016896 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016897 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016898 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070016899 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016900 maxMCSIdx = 7;
16901 }
16902 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
16903 {
16904 maxMCSIdx = 8;
16905 }
16906 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
16907 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016908 //VHT20 is supporting 0~8
16909 if (rate_flags & eHAL_TX_RATE_VHT20)
16910 maxMCSIdx = 8;
16911 else
16912 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070016913 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016914
c_hpothu79aab322014-07-14 21:11:01 +053016915 if (0 != rssidx)/*check for scaled */
16916 {
16917 //get middle rate MCS index if rssi=1/2
16918 for (i=0; i <= maxMCSIdx; i++)
16919 {
16920 if (sinfo->signal <= rssiMcsTbl[mode][i])
16921 {
16922 maxMCSIdx = i;
16923 break;
16924 }
16925 }
16926 }
16927
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016928 if (rate_flags & eHAL_TX_RATE_VHT80)
16929 {
16930 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
16931 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
16932 }
16933 else if (rate_flags & eHAL_TX_RATE_VHT40)
16934 {
16935 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
16936 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
16937 }
16938 else if (rate_flags & eHAL_TX_RATE_VHT20)
16939 {
16940 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
16941 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
16942 }
16943
Leo Chang6f8870f2013-03-26 18:11:36 -070016944 maxSpeedMCS = 1;
16945 if (currentRate > maxRate)
16946 {
16947 maxRate = currentRate;
16948 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016949
Leo Chang6f8870f2013-03-26 18:11:36 -070016950 }
16951 else
16952#endif /* WLAN_FEATURE_11AC */
16953 {
16954 if (rate_flags & eHAL_TX_RATE_HT40)
16955 {
16956 rateFlag |= 1;
16957 }
16958 if (rate_flags & eHAL_TX_RATE_SGI)
16959 {
16960 rateFlag |= 2;
16961 }
16962
Girish Gowli01abcee2014-07-31 20:18:55 +053016963 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053016964 if (rssidx == 1 || rssidx == 2)
16965 {
16966 //get middle rate MCS index if rssi=1/2
16967 for (i=0; i <= 7; i++)
16968 {
16969 if (sinfo->signal <= rssiMcsTbl[mode][i])
16970 {
16971 temp = i+1;
16972 break;
16973 }
16974 }
16975 }
c_hpothu79aab322014-07-14 21:11:01 +053016976
16977 for (i = 0; i < MCSLeng; i++)
16978 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016979 for (j = 0; j < temp; j++)
16980 {
16981 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
16982 {
16983 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016984 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016985 break;
16986 }
16987 }
16988 if ((j < temp) && (currentRate > maxRate))
16989 {
16990 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070016991 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016992 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016993 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016994 }
16995 }
16996
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016997 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
16998 {
16999 maxRate = myRate;
17000 maxSpeedMCS = 1;
17001 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17002 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017003 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053017004 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070017005 {
17006 maxRate = myRate;
17007 if (rate_flags & eHAL_TX_RATE_LEGACY)
17008 {
17009 maxSpeedMCS = 0;
17010 }
17011 else
17012 {
17013 maxSpeedMCS = 1;
17014 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17015 }
17016 }
17017
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017018 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070017019 {
17020 sinfo->txrate.legacy = maxRate;
17021#ifdef LINKSPEED_DEBUG_ENABLED
17022 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
17023#endif //LINKSPEED_DEBUG_ENABLED
17024 }
17025 else
17026 {
17027 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070017028#ifdef WLAN_FEATURE_11AC
17029 sinfo->txrate.nss = 1;
17030 if (rate_flags & eHAL_TX_RATE_VHT80)
17031 {
17032 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017033 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070017034 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017035 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070017036 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017037 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17038 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17039 }
17040 else if (rate_flags & eHAL_TX_RATE_VHT20)
17041 {
17042 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17043 }
17044#endif /* WLAN_FEATURE_11AC */
17045 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
17046 {
17047 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17048 if (rate_flags & eHAL_TX_RATE_HT40)
17049 {
17050 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17051 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017052 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017053 if (rate_flags & eHAL_TX_RATE_SGI)
17054 {
17055 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17056 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017057
Jeff Johnson295189b2012-06-20 16:38:30 -070017058#ifdef LINKSPEED_DEBUG_ENABLED
17059 pr_info("Reporting MCS rate %d flags %x\n",
17060 sinfo->txrate.mcs,
17061 sinfo->txrate.flags );
17062#endif //LINKSPEED_DEBUG_ENABLED
17063 }
17064 }
17065 else
17066 {
17067 // report current rate instead of max rate
17068
17069 if (rate_flags & eHAL_TX_RATE_LEGACY)
17070 {
17071 //provide to the UI in units of 100kbps
17072 sinfo->txrate.legacy = myRate;
17073#ifdef LINKSPEED_DEBUG_ENABLED
17074 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
17075#endif //LINKSPEED_DEBUG_ENABLED
17076 }
17077 else
17078 {
17079 //must be MCS
17080 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017081#ifdef WLAN_FEATURE_11AC
17082 sinfo->txrate.nss = 1;
17083 if (rate_flags & eHAL_TX_RATE_VHT80)
17084 {
17085 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17086 }
17087 else
17088#endif /* WLAN_FEATURE_11AC */
17089 {
17090 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17091 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017092 if (rate_flags & eHAL_TX_RATE_SGI)
17093 {
17094 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17095 }
17096 if (rate_flags & eHAL_TX_RATE_HT40)
17097 {
17098 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17099 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017100#ifdef WLAN_FEATURE_11AC
17101 else if (rate_flags & eHAL_TX_RATE_VHT80)
17102 {
17103 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
17104 }
17105#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070017106#ifdef LINKSPEED_DEBUG_ENABLED
17107 pr_info("Reporting actual MCS rate %d flags %x\n",
17108 sinfo->txrate.mcs,
17109 sinfo->txrate.flags );
17110#endif //LINKSPEED_DEBUG_ENABLED
17111 }
17112 }
17113 sinfo->filled |= STATION_INFO_TX_BITRATE;
17114
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017115 sinfo->tx_packets =
17116 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
17117 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
17118 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
17119 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
17120
17121 sinfo->tx_retries =
17122 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
17123 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
17124 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
17125 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
17126
17127 sinfo->tx_failed =
17128 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
17129 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
17130 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
17131 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
17132
17133 sinfo->filled |=
17134 STATION_INFO_TX_PACKETS |
17135 STATION_INFO_TX_RETRIES |
17136 STATION_INFO_TX_FAILED;
17137
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017138 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
17139 sinfo->filled |= STATION_INFO_RX_PACKETS;
17140
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017141 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
17142 &sinfo->txrate, sizeof(sinfo->txrate));
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017143 if (rate_flags & eHAL_TX_RATE_LEGACY)
17144 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
17145 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
17146 sinfo->rx_packets);
17147 else
17148 hddLog(LOG1,
17149 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
17150 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
17151 sinfo->tx_packets, sinfo->rx_packets);
17152
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017153 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17154 TRACE_CODE_HDD_CFG80211_GET_STA,
17155 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017156 EXIT();
17157 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017158}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017159#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17160static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17161 const u8* mac, struct station_info *sinfo)
17162#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017163static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17164 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017165#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017166{
17167 int ret;
17168
17169 vos_ssr_protect(__func__);
17170 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
17171 vos_ssr_unprotect(__func__);
17172
17173 return ret;
17174}
17175
17176static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070017177 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070017178{
17179 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017180 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017181 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017182 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017183
Jeff Johnsone7245742012-09-05 17:12:55 -070017184 ENTER();
17185
Jeff Johnson295189b2012-06-20 16:38:30 -070017186 if (NULL == pAdapter)
17187 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017188 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017189 return -ENODEV;
17190 }
17191
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017192 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17193 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
17194 pAdapter->sessionId, timeout));
17195
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017196 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017197 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017198 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017199 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017200 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017201 }
17202
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017203 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
17204 (TRUE == pHddCtx->hdd_wlan_suspended) &&
17205 (pHddCtx->cfg_ini->fhostArpOffload) &&
17206 (eConnectionState_Associated ==
17207 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
17208 {
Amar Singhald53568e2013-09-26 11:03:45 -070017209
17210 hddLog(VOS_TRACE_LEVEL_INFO,
17211 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053017212 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017213 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17214 {
17215 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017216 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017217 __func__, vos_status);
17218 }
17219 }
17220
Jeff Johnson295189b2012-06-20 16:38:30 -070017221 /**The get power cmd from the supplicant gets updated by the nl only
17222 *on successful execution of the function call
17223 *we are oppositely mapped w.r.t mode in the driver
17224 **/
17225 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
17226
17227 if (VOS_STATUS_E_FAILURE == vos_status)
17228 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017229 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17230 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017231 return -EINVAL;
17232 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017233 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017234 return 0;
17235}
17236
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017237static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
17238 struct net_device *dev, bool mode, int timeout)
17239{
17240 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017241
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017242 vos_ssr_protect(__func__);
17243 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
17244 vos_ssr_unprotect(__func__);
17245
17246 return ret;
17247}
Sushant Kaushik084f6592015-09-10 13:11:56 +053017248
Jeff Johnson295189b2012-06-20 16:38:30 -070017249#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017250static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
17251 struct net_device *netdev,
17252 u8 key_index)
17253{
17254 ENTER();
17255 return 0;
17256}
17257
Jeff Johnson295189b2012-06-20 16:38:30 -070017258static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017259 struct net_device *netdev,
17260 u8 key_index)
17261{
17262 int ret;
17263 vos_ssr_protect(__func__);
17264 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
17265 vos_ssr_unprotect(__func__);
17266 return ret;
17267}
17268#endif //LINUX_VERSION_CODE
17269
17270#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17271static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17272 struct net_device *dev,
17273 struct ieee80211_txq_params *params)
17274{
17275 ENTER();
17276 return 0;
17277}
17278#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17279static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17280 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017281{
Jeff Johnsone7245742012-09-05 17:12:55 -070017282 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070017283 return 0;
17284}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017285#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070017286
17287#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17288static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017289 struct net_device *dev,
17290 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017291{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017292 int ret;
17293
17294 vos_ssr_protect(__func__);
17295 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
17296 vos_ssr_unprotect(__func__);
17297 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017298}
17299#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17300static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
17301 struct ieee80211_txq_params *params)
17302{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017303 int ret;
17304
17305 vos_ssr_protect(__func__);
17306 ret = __wlan_hdd_set_txq_params(wiphy, params);
17307 vos_ssr_unprotect(__func__);
17308 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017309}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017310#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017311
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017312static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017313 struct net_device *dev,
17314 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070017315{
17316 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017317 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017318 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017319 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017320 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017321 v_CONTEXT_t pVosContext = NULL;
17322 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017323
Jeff Johnsone7245742012-09-05 17:12:55 -070017324 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017325
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017326 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070017327 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017328 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017329 return -EINVAL;
17330 }
17331
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017332 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17333 TRACE_CODE_HDD_CFG80211_DEL_STA,
17334 pAdapter->sessionId, pAdapter->device_mode));
17335
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017336 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17337 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017338 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017339 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017340 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017341 }
17342
Jeff Johnson295189b2012-06-20 16:38:30 -070017343 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017344 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017345 )
17346 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017347 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
17348 pSapCtx = VOS_GET_SAP_CB(pVosContext);
17349 if(pSapCtx == NULL){
17350 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17351 FL("psapCtx is NULL"));
17352 return -ENOENT;
17353 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053017354 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
17355 {
17356 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
17357 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
17358 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
17359 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017360 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070017361 {
17362 v_U16_t i;
17363 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
17364 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017365 if ((pSapCtx->aStaInfo[i].isUsed) &&
17366 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070017367 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017368 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017369 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017370 ETHER_ADDR_LEN);
17371
Jeff Johnson295189b2012-06-20 16:38:30 -070017372 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017373 "%s: Delete STA with MAC::"
17374 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017375 __func__,
17376 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
17377 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070017378 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017379 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017380 }
17381 }
17382 }
17383 else
17384 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017385
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017386 vos_status = hdd_softap_GetStaId(pAdapter,
17387 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017388 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17389 {
17390 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017391 "%s: Skip this DEL STA as this is not used::"
17392 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017393 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017394 return -ENOENT;
17395 }
17396
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017397 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017398 {
17399 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017400 "%s: Skip this DEL STA as deauth is in progress::"
17401 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017402 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017403 return -ENOENT;
17404 }
17405
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017406 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017407
Jeff Johnson295189b2012-06-20 16:38:30 -070017408 hddLog(VOS_TRACE_LEVEL_INFO,
17409 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080017410 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017411 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017412 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017413
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017414 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017415 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17416 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017417 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017418 hddLog(VOS_TRACE_LEVEL_INFO,
17419 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080017420 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017421 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017422 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017423 return -ENOENT;
17424 }
17425
Jeff Johnson295189b2012-06-20 16:38:30 -070017426 }
17427 }
17428
17429 EXIT();
17430
17431 return 0;
17432}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017433
17434#ifdef CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053017435int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017436 struct net_device *dev,
17437 struct station_del_parameters *param)
17438#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017439#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053017440int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017441 struct net_device *dev, const u8 *mac)
17442#else
Kapil Gupta137ef892016-12-13 19:38:00 +053017443int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017444 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017445#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017446#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017447{
17448 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017449 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070017450
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017451 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017452
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017453#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017454 if (NULL == param) {
17455 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017456 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017457 return -EINVAL;
17458 }
17459
17460 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
17461 param->subtype, &delStaParams);
17462
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017463#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053017464 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017465 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017466#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017467 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
17468
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017469 vos_ssr_unprotect(__func__);
17470
17471 return ret;
17472}
17473
17474static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017475 struct net_device *dev,
17476#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17477 const u8 *mac,
17478#else
17479 u8 *mac,
17480#endif
17481 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017482{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017483 hdd_adapter_t *pAdapter;
17484 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017485 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017486#ifdef FEATURE_WLAN_TDLS
17487 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017488
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017489 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017490
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017491 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17492 if (NULL == pAdapter)
17493 {
17494 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17495 "%s: Adapter is NULL",__func__);
17496 return -EINVAL;
17497 }
17498 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17499 status = wlan_hdd_validate_context(pHddCtx);
17500 if (0 != status)
17501 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017502 return status;
17503 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017504
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017505 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17506 TRACE_CODE_HDD_CFG80211_ADD_STA,
17507 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017508 mask = params->sta_flags_mask;
17509
17510 set = params->sta_flags_set;
17511
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017513 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
17514 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017515
17516 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
17517 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080017518 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017519 }
17520 }
17521#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017522 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017523 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017524}
17525
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017526#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17527static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
17528 struct net_device *dev, const u8 *mac,
17529 struct station_parameters *params)
17530#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017531static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
17532 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017533#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017534{
17535 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017536
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017537 vos_ssr_protect(__func__);
17538 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
17539 vos_ssr_unprotect(__func__);
17540
17541 return ret;
17542}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017543#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070017544
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017545static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070017546 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017547{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017548 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17549 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017550 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017551 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017552 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017553 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070017554
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017555 ENTER();
17556
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017557 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017558 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017559 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017560 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017561 return -EINVAL;
17562 }
17563
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017564 if (!pmksa) {
17565 hddLog(LOGE, FL("pmksa is NULL"));
17566 return -EINVAL;
17567 }
17568
17569 if (!pmksa->bssid || !pmksa->pmkid) {
17570 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
17571 pmksa->bssid, pmksa->pmkid);
17572 return -EINVAL;
17573 }
17574
17575 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
17576 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17577
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017578 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17579 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017580 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017581 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017582 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017583 }
17584
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017585 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017586 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17587
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017588 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
17589 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017590
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017591 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017592 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017593 &pmk_id, 1, FALSE);
17594
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017595 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17596 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
17597 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017598
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017599 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017600 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017601}
17602
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017603static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
17604 struct cfg80211_pmksa *pmksa)
17605{
17606 int ret;
17607
17608 vos_ssr_protect(__func__);
17609 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
17610 vos_ssr_unprotect(__func__);
17611
17612 return ret;
17613}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017614
Wilson Yang6507c4e2013-10-01 20:11:19 -070017615
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017616static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070017617 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017618{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017619 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17620 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017621 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017622 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017623
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017624 ENTER();
17625
Wilson Yang6507c4e2013-10-01 20:11:19 -070017626 /* Validate pAdapter */
17627 if (NULL == pAdapter)
17628 {
17629 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
17630 return -EINVAL;
17631 }
17632
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017633 if (!pmksa) {
17634 hddLog(LOGE, FL("pmksa is NULL"));
17635 return -EINVAL;
17636 }
17637
17638 if (!pmksa->bssid) {
17639 hddLog(LOGE, FL("pmksa->bssid is NULL"));
17640 return -EINVAL;
17641 }
17642
Kiet Lam98c46a12014-10-31 15:34:57 -070017643 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
17644 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17645
Wilson Yang6507c4e2013-10-01 20:11:19 -070017646 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17647 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017648 if (0 != status)
17649 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017650 return status;
17651 }
17652
17653 /*Retrieve halHandle*/
17654 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17655
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017656 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17657 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
17658 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017659 /* Delete the PMKID CSR cache */
17660 if (eHAL_STATUS_SUCCESS !=
17661 sme_RoamDelPMKIDfromCache(halHandle,
17662 pAdapter->sessionId, pmksa->bssid, FALSE)) {
17663 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
17664 MAC_ADDR_ARRAY(pmksa->bssid));
17665 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017666 }
17667
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017668 EXIT();
17669 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017670}
17671
Wilson Yang6507c4e2013-10-01 20:11:19 -070017672
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017673static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
17674 struct cfg80211_pmksa *pmksa)
17675{
17676 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017677
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017678 vos_ssr_protect(__func__);
17679 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
17680 vos_ssr_unprotect(__func__);
17681
17682 return ret;
17683
17684}
17685
17686static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017687{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017688 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17689 tHalHandle halHandle;
17690 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017691 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017692
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017693 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070017694
17695 /* Validate pAdapter */
17696 if (NULL == pAdapter)
17697 {
17698 hddLog(VOS_TRACE_LEVEL_ERROR,
17699 "%s: Invalid Adapter" ,__func__);
17700 return -EINVAL;
17701 }
17702
17703 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17704 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017705 if (0 != status)
17706 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017707 return status;
17708 }
17709
17710 /*Retrieve halHandle*/
17711 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17712
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017713 /* Flush the PMKID cache in CSR */
17714 if (eHAL_STATUS_SUCCESS !=
17715 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
17716 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
17717 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017718 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017719 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080017720 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017721}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017722
17723static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
17724{
17725 int ret;
17726
17727 vos_ssr_protect(__func__);
17728 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
17729 vos_ssr_unprotect(__func__);
17730
17731 return ret;
17732}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017733#endif
17734
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017735#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017736static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17737 struct net_device *dev,
17738 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017739{
17740 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17741 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017742 hdd_context_t *pHddCtx;
17743 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017744
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017745 ENTER();
17746
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017747 if (NULL == pAdapter)
17748 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017749 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017750 return -ENODEV;
17751 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017752 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17753 ret = wlan_hdd_validate_context(pHddCtx);
17754 if (0 != ret)
17755 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017756 return ret;
17757 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017758 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017759 if (NULL == pHddStaCtx)
17760 {
17761 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
17762 return -EINVAL;
17763 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017764
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017765 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17766 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
17767 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017768 // Added for debug on reception of Re-assoc Req.
17769 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
17770 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017771 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017772 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080017773 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017774 }
17775
17776#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080017777 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017778 ftie->ie_len);
17779#endif
17780
17781 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053017782 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
17783 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017784 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017785
17786 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017787 return 0;
17788}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017789
17790static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17791 struct net_device *dev,
17792 struct cfg80211_update_ft_ies_params *ftie)
17793{
17794 int ret;
17795
17796 vos_ssr_protect(__func__);
17797 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
17798 vos_ssr_unprotect(__func__);
17799
17800 return ret;
17801}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017802#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017803
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017804#ifdef FEATURE_WLAN_SCAN_PNO
17805
17806void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
17807 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
17808{
17809 int ret;
17810 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
17811 hdd_context_t *pHddCtx;
17812
Nirav Shah80830bf2013-12-31 16:35:12 +053017813 ENTER();
17814
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017815 if (NULL == pAdapter)
17816 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053017817 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017818 "%s: HDD adapter is Null", __func__);
17819 return ;
17820 }
17821
17822 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17823 if (NULL == pHddCtx)
17824 {
17825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17826 "%s: HDD context is Null!!!", __func__);
17827 return ;
17828 }
17829
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017830 spin_lock(&pHddCtx->schedScan_lock);
17831 if (TRUE == pHddCtx->isWiphySuspended)
17832 {
17833 pHddCtx->isSchedScanUpdatePending = TRUE;
17834 spin_unlock(&pHddCtx->schedScan_lock);
17835 hddLog(VOS_TRACE_LEVEL_INFO,
17836 "%s: Update cfg80211 scan database after it resume", __func__);
17837 return ;
17838 }
17839 spin_unlock(&pHddCtx->schedScan_lock);
17840
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017841 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
17842
17843 if (0 > ret)
17844 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053017845 else
17846 {
17847 /* Acquire wakelock to handle the case where APP's tries to suspend
17848 * immediatly after the driver gets connect request(i.e after pno)
17849 * from supplicant, this result in app's is suspending and not able
17850 * to process the connect request to AP */
17851 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
17852 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017853 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017854 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17855 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017856}
17857
17858/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017859 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017860 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017861 */
17862static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
17863{
17864 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
17865 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017866 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017867 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17868 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053017869
17870 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
17871 {
17872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17873 "%s: PNO is allowed only in STA interface", __func__);
17874 return eHAL_STATUS_FAILURE;
17875 }
17876
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017877 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
17878
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017879 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053017880 * active sessions. PNO is allowed only in case when sap session
17881 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017882 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017883 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
17884 {
17885 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017886 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017887
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017888 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
17889 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
17890 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
17891 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053017892 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
17893 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053017894 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017895 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017896 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017897 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017898 }
17899 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17900 pAdapterNode = pNext;
17901 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017902 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017903}
17904
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017905void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
17906{
17907 hdd_adapter_t *pAdapter = callbackContext;
17908 hdd_context_t *pHddCtx;
17909
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017910 ENTER();
17911
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017912 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
17913 {
17914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17915 FL("Invalid adapter or adapter has invalid magic"));
17916 return;
17917 }
17918
17919 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17920 if (0 != wlan_hdd_validate_context(pHddCtx))
17921 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017922 return;
17923 }
17924
c_hpothub53c45d2014-08-18 16:53:14 +053017925 if (VOS_STATUS_SUCCESS != status)
17926 {
17927 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017928 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053017929 pHddCtx->isPnoEnable = FALSE;
17930 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017931
17932 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
17933 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017934 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017935}
17936
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017937#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
17938 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
17939/**
17940 * hdd_config_sched_scan_plan() - configures the sched scan plans
17941 * from the framework.
17942 * @pno_req: pointer to PNO scan request
17943 * @request: pointer to scan request from framework
17944 *
17945 * Return: None
17946 */
17947static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
17948 struct cfg80211_sched_scan_request *request,
17949 hdd_context_t *hdd_ctx)
17950{
17951 v_U32_t i = 0;
17952
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017953 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017954 for (i = 0; i < request->n_scan_plans; i++)
17955 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017956 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
17957 request->scan_plans[i].iterations;
17958 pno_req->scanTimers.aTimerValues[i].uTimerValue =
17959 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017960 }
17961}
17962#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017963static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017964 struct cfg80211_sched_scan_request *request,
17965 hdd_context_t *hdd_ctx)
17966{
17967 v_U32_t i, temp_int;
17968 /* Driver gets only one time interval which is hardcoded in
17969 * supplicant for 10000ms. Taking power consumption into account 6
17970 * timers will be used, Timervalue is increased exponentially
17971 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
17972 * timer is configurable through INI param gPNOScanTimerRepeatValue.
17973 * If it is set to 0 only one timer will be used and PNO scan cycle
17974 * will be repeated after each interval specified by supplicant
17975 * till PNO is disabled.
17976 */
17977 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017978 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017979 HDD_PNO_SCAN_TIMERS_SET_ONE;
17980 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017981 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017982 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
17983
17984 temp_int = (request->interval)/1000;
17985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17986 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
17987 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017988 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017989 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017990 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017991 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017992 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017993 temp_int *= 2;
17994 }
17995 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017996 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017997}
17998#endif
17999
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018000/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018001 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
18002 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018003 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018004static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018005 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18006{
18007 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018008 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018009 hdd_context_t *pHddCtx;
18010 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018011 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053018012 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
18013 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018014 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
18015 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018016 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018017 hdd_config_t *pConfig = NULL;
18018 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018019
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018020 ENTER();
18021
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018022 if (NULL == pAdapter)
18023 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018025 "%s: HDD adapter is Null", __func__);
18026 return -ENODEV;
18027 }
18028
18029 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018030 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018031
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018032 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018033 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018034 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018035 }
18036
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018037 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018038 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18039 if (NULL == hHal)
18040 {
18041 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18042 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018043 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018044 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018045 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18046 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
18047 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018048 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053018049 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018050 {
18051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18052 "%s: aborting the existing scan is unsuccessfull", __func__);
18053 return -EBUSY;
18054 }
18055
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018056 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018057 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018059 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018060 return -EBUSY;
18061 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018062
c_hpothu37f21312014-04-09 21:49:54 +053018063 if (TRUE == pHddCtx->isPnoEnable)
18064 {
18065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
18066 FL("already PNO is enabled"));
18067 return -EBUSY;
18068 }
c_hpothu225aa7c2014-10-22 17:45:13 +053018069
18070 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
18071 {
18072 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18073 "%s: abort ROC failed ", __func__);
18074 return -EBUSY;
18075 }
18076
c_hpothu37f21312014-04-09 21:49:54 +053018077 pHddCtx->isPnoEnable = TRUE;
18078
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018079 pnoRequest.enable = 1; /*Enable PNO */
18080 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018081
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018082 if (( !pnoRequest.ucNetworksCount ) ||
18083 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018084 {
18085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018086 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018087 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018088 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018089 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018090 goto error;
18091 }
18092
18093 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
18094 {
18095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018096 "%s: Incorrect number of channels %d",
18097 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018098 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018099 goto error;
18100 }
18101
18102 /* Framework provides one set of channels(all)
18103 * common for all saved profile */
18104 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
18105 channels_allowed, &num_channels_allowed))
18106 {
18107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18108 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018109 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018110 goto error;
18111 }
18112 /* Checking each channel against allowed channel list */
18113 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053018114 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018115 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018116 char chList [(request->n_channels*5)+1];
18117 int len;
18118 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018119 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018120 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018121 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018122 if (request->channels[i]->hw_value == channels_allowed[indx])
18123 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018124 if ((!pConfig->enableDFSPnoChnlScan) &&
18125 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
18126 {
18127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18128 "%s : Dropping DFS channel : %d",
18129 __func__,channels_allowed[indx]);
18130 num_ignore_dfs_ch++;
18131 break;
18132 }
18133
Nirav Shah80830bf2013-12-31 16:35:12 +053018134 valid_ch[num_ch++] = request->channels[i]->hw_value;
18135 len += snprintf(chList+len, 5, "%d ",
18136 request->channels[i]->hw_value);
18137 break ;
18138 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018139 }
18140 }
Nirav Shah80830bf2013-12-31 16:35:12 +053018141 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018142
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018143 /*If all channels are DFS and dropped, then ignore the PNO request*/
18144 if (num_ignore_dfs_ch == request->n_channels)
18145 {
18146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18147 "%s : All requested channels are DFS channels", __func__);
18148 ret = -EINVAL;
18149 goto error;
18150 }
18151 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018152
18153 pnoRequest.aNetworks =
18154 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18155 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018156 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018157 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18158 FL("failed to allocate memory aNetworks %u"),
18159 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18160 goto error;
18161 }
18162 vos_mem_zero(pnoRequest.aNetworks,
18163 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18164
18165 /* Filling per profile params */
18166 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
18167 {
18168 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018169 request->match_sets[i].ssid.ssid_len;
18170
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018171 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
18172 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018173 {
18174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018175 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018176 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018177 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018178 goto error;
18179 }
18180
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018181 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018182 request->match_sets[i].ssid.ssid,
18183 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18185 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018186 i, pnoRequest.aNetworks[i].ssId.ssId);
18187 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
18188 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
18189 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018190
18191 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018192 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
18193 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018194
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018195 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018196 }
18197
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018198 for (i = 0; i < request->n_ssids; i++)
18199 {
18200 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018201 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018202 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018203 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018204 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018205 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018206 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018207 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018208 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018209 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018210 break;
18211 }
18212 j++;
18213 }
18214 }
18215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18216 "Number of hidden networks being Configured = %d",
18217 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080018219 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018220
18221 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18222 if (pnoRequest.p24GProbeTemplate == NULL)
18223 {
18224 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18225 FL("failed to allocate memory p24GProbeTemplate %u"),
18226 SIR_PNO_MAX_PB_REQ_SIZE);
18227 goto error;
18228 }
18229
18230 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18231 if (pnoRequest.p5GProbeTemplate == NULL)
18232 {
18233 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18234 FL("failed to allocate memory p5GProbeTemplate %u"),
18235 SIR_PNO_MAX_PB_REQ_SIZE);
18236 goto error;
18237 }
18238
18239 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18240 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18241
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053018242 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
18243 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018244 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018245 pnoRequest.us24GProbeTemplateLen = request->ie_len;
18246 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
18247 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018248
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018249 pnoRequest.us5GProbeTemplateLen = request->ie_len;
18250 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
18251 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018252 }
18253
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018254 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053018255
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018256 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018257
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018258 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018259 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
18260 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018261 pAdapter->pno_req_status = 0;
18262
Nirav Shah80830bf2013-12-31 16:35:12 +053018263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18264 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018265 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
18266 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053018267
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018268 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018269 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018270 hdd_cfg80211_sched_scan_done_callback, pAdapter);
18271 if (eHAL_STATUS_SUCCESS != status)
18272 {
18273 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018274 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018275 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018276 goto error;
18277 }
18278
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018279 ret = wait_for_completion_timeout(
18280 &pAdapter->pno_comp_var,
18281 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
18282 if (0 >= ret)
18283 {
18284 // Did not receive the response for PNO enable in time.
18285 // Assuming the PNO enable was success.
18286 // Returning error from here, because we timeout, results
18287 // in side effect of Wifi (Wifi Setting) not to work.
18288 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18289 FL("Timed out waiting for PNO to be Enabled"));
18290 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018291 }
18292
18293 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053018294 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018295
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018296error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18298 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053018299 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018300 if (pnoRequest.aNetworks)
18301 vos_mem_free(pnoRequest.aNetworks);
18302 if (pnoRequest.p24GProbeTemplate)
18303 vos_mem_free(pnoRequest.p24GProbeTemplate);
18304 if (pnoRequest.p5GProbeTemplate)
18305 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018306
18307 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018308 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018309}
18310
18311/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018312 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
18313 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018314 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018315static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
18316 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18317{
18318 int ret;
18319
18320 vos_ssr_protect(__func__);
18321 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
18322 vos_ssr_unprotect(__func__);
18323
18324 return ret;
18325}
18326
18327/*
18328 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
18329 * Function to disable PNO
18330 */
18331static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018332 struct net_device *dev)
18333{
18334 eHalStatus status = eHAL_STATUS_FAILURE;
18335 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18336 hdd_context_t *pHddCtx;
18337 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018338 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018339 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018340
18341 ENTER();
18342
18343 if (NULL == pAdapter)
18344 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018345 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018346 "%s: HDD adapter is Null", __func__);
18347 return -ENODEV;
18348 }
18349
18350 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018351
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018352 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018353 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018354 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018355 "%s: HDD context is Null", __func__);
18356 return -ENODEV;
18357 }
18358
18359 /* The return 0 is intentional when isLogpInProgress and
18360 * isLoadUnloadInProgress. We did observe a crash due to a return of
18361 * failure in sched_scan_stop , especially for a case where the unload
18362 * of the happens at the same time. The function __cfg80211_stop_sched_scan
18363 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
18364 * success. If it returns a failure , then its next invocation due to the
18365 * clean up of the second interface will have the dev pointer corresponding
18366 * to the first one leading to a crash.
18367 */
18368 if (pHddCtx->isLogpInProgress)
18369 {
18370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18371 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053018372 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018373 return ret;
18374 }
18375
Mihir Shete18156292014-03-11 15:38:30 +053018376 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018377 {
18378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18379 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
18380 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018381 }
18382
18383 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18384 if (NULL == hHal)
18385 {
18386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18387 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018388 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018389 }
18390
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018391 pnoRequest.enable = 0; /* Disable PNO */
18392 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018393
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018394 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18395 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
18396 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018397
18398 INIT_COMPLETION(pAdapter->pno_comp_var);
18399 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
18400 pnoRequest.callbackContext = pAdapter;
18401 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018402 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018403 pAdapter->sessionId,
18404 NULL, pAdapter);
18405 if (eHAL_STATUS_SUCCESS != status)
18406 {
18407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18408 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018409 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018410 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018411 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018412 ret = wait_for_completion_timeout(
18413 &pAdapter->pno_comp_var,
18414 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
18415 if (0 >= ret)
18416 {
18417 // Did not receive the response for PNO disable in time.
18418 // Assuming the PNO disable was success.
18419 // Returning error from here, because we timeout, results
18420 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053018421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018422 FL("Timed out waiting for PNO to be disabled"));
18423 ret = 0;
18424 }
18425
18426 ret = pAdapter->pno_req_status;
18427 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018428
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018429error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018431 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018432
18433 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018434 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018435}
18436
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018437/*
18438 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
18439 * NL interface to disable PNO
18440 */
18441static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
18442 struct net_device *dev)
18443{
18444 int ret;
18445
18446 vos_ssr_protect(__func__);
18447 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
18448 vos_ssr_unprotect(__func__);
18449
18450 return ret;
18451}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018452#endif /*FEATURE_WLAN_SCAN_PNO*/
18453
18454
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018455#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018456#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018457static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18458 struct net_device *dev,
18459 u8 *peer, u8 action_code,
18460 u8 dialog_token,
18461 u16 status_code, u32 peer_capability,
18462 const u8 *buf, size_t len)
18463#else /* TDLS_MGMT_VERSION2 */
18464#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
18465static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18466 struct net_device *dev,
18467 const u8 *peer, u8 action_code,
18468 u8 dialog_token, u16 status_code,
18469 u32 peer_capability, bool initiator,
18470 const u8 *buf, size_t len)
18471#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
18472static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18473 struct net_device *dev,
18474 const u8 *peer, u8 action_code,
18475 u8 dialog_token, u16 status_code,
18476 u32 peer_capability, const u8 *buf,
18477 size_t len)
18478#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
18479static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18480 struct net_device *dev,
18481 u8 *peer, u8 action_code,
18482 u8 dialog_token,
18483 u16 status_code, u32 peer_capability,
18484 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018485#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018486static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18487 struct net_device *dev,
18488 u8 *peer, u8 action_code,
18489 u8 dialog_token,
18490 u16 status_code, const u8 *buf,
18491 size_t len)
18492#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018493#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018494{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018495 hdd_adapter_t *pAdapter;
18496 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018497 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070018498 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080018499 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070018500 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018501 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053018502 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018503#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018504 u32 peer_capability = 0;
18505#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018506 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018507 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018508 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018509
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018510 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18511 if (NULL == pAdapter)
18512 {
18513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18514 "%s: Adapter is NULL",__func__);
18515 return -EINVAL;
18516 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018517 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18518 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
18519 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018520
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018521 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018522 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018523 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018525 "Invalid arguments");
18526 return -EINVAL;
18527 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018528
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018529 if (pHddCtx->isLogpInProgress)
18530 {
18531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18532 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053018533 wlan_hdd_tdls_set_link_status(pAdapter,
18534 peer,
18535 eTDLS_LINK_IDLE,
18536 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018537 return -EBUSY;
18538 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018539
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018540 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
18541 {
18542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18543 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
18544 return -EAGAIN;
18545 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018546
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018547 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
18548 if (!pHddTdlsCtx) {
18549 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18550 "%s: pHddTdlsCtx not valid.", __func__);
18551 }
18552
Hoonki Lee27511902013-03-14 18:19:06 -070018553 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018554 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018556 "%s: TDLS mode is disabled OR not enabled in FW."
18557 MAC_ADDRESS_STR " action %d declined.",
18558 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018559 return -ENOTSUPP;
18560 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018561
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018562 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18563
18564 if( NULL == pHddStaCtx )
18565 {
18566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18567 "%s: HDD station context NULL ",__func__);
18568 return -EINVAL;
18569 }
18570
18571 /* STA should be connected and authenticated
18572 * before sending any TDLS frames
18573 */
18574 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18575 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
18576 {
18577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18578 "STA is not connected or unauthenticated. "
18579 "connState %u, uIsAuthenticated %u",
18580 pHddStaCtx->conn_info.connState,
18581 pHddStaCtx->conn_info.uIsAuthenticated);
18582 return -EAGAIN;
18583 }
18584
Hoonki Lee27511902013-03-14 18:19:06 -070018585 /* other than teardown frame, other mgmt frames are not sent if disabled */
18586 if (SIR_MAC_TDLS_TEARDOWN != action_code)
18587 {
18588 /* if tdls_mode is disabled to respond to peer's request */
18589 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
18590 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018592 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018593 " TDLS mode is disabled. action %d declined.",
18594 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070018595
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018596 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070018597 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053018598
18599 if (vos_max_concurrent_connections_reached())
18600 {
18601 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
18602 return -EINVAL;
18603 }
Hoonki Lee27511902013-03-14 18:19:06 -070018604 }
18605
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018606 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
18607 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053018608 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018609 {
18610 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018611 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018612 " TDLS setup is ongoing. action %d declined.",
18613 __func__, MAC_ADDR_ARRAY(peer), action_code);
18614 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018615 }
18616 }
18617
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018618 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
18619 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080018620 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018621 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18622 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018623 {
18624 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
18625 we return error code at 'add_station()'. Hence we have this
18626 check again in addtion to add_station().
18627 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018628 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018629 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018630 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18631 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018632 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
18633 __func__, MAC_ADDR_ARRAY(peer), action_code,
18634 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053018635 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080018636 }
18637 else
18638 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018639 /* maximum reached. tweak to send error code to peer and return
18640 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018641 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18643 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018644 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
18645 __func__, MAC_ADDR_ARRAY(peer), status_code,
18646 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070018647 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018648 /* fall through to send setup resp with failure status
18649 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018650 }
18651 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018652 else
18653 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018654 mutex_lock(&pHddCtx->tdls_lock);
18655 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018656 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018657 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018658 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018660 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
18661 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018662 return -EPERM;
18663 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018664 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018665 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018666 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018667
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018669 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018670 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
18671 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018672
Hoonki Leea34dd892013-02-05 22:56:02 -080018673 /*Except teardown responder will not be used so just make 0*/
18674 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018675 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080018676 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018677
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018678 mutex_lock(&pHddCtx->tdls_lock);
18679 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018680
18681 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
18682 responder = pTdlsPeer->is_responder;
18683 else
Hoonki Leea34dd892013-02-05 22:56:02 -080018684 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018686 "%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 -070018687 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
18688 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018689 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018690 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080018691 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018692 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018693 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018694
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053018695 /* Discard TDLS setup if peer is removed by user app */
18696 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
18697 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18698 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
18699 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
18700
18701 mutex_lock(&pHddCtx->tdls_lock);
18702 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18703 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
18704 mutex_unlock(&pHddCtx->tdls_lock);
18705 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
18706 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
18707 MAC_ADDR_ARRAY(peer), action_code);
18708 return -EINVAL;
18709 }
18710 mutex_unlock(&pHddCtx->tdls_lock);
18711 }
18712
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018713 /* For explicit trigger of DIS_REQ come out of BMPS for
18714 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070018715 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053018716 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018717 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
18718 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070018719 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018720 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018722 "%s: Sending frame action_code %u.Disable BMPS", __func__,
18723 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018724 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
18725 if (status != VOS_STATUS_SUCCESS) {
18726 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018727 } else {
18728 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018729 }
Hoonki Lee14621352013-04-16 17:51:19 -070018730 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018731 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018732 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018733 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
18734 }
18735 }
Hoonki Lee14621352013-04-16 17:51:19 -070018736 }
18737
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018738 /* make sure doesn't call send_mgmt() while it is pending */
18739 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
18740 {
18741 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018742 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018743 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018744 ret = -EBUSY;
18745 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018746 }
18747
18748 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018749 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
18750
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018751 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
18752 pAdapter->sessionId, peer, action_code, dialog_token,
18753 status_code, peer_capability, (tANI_U8 *)buf, len,
18754 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018755
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018756 if (VOS_STATUS_SUCCESS != status)
18757 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18759 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018760 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018761 ret = -EINVAL;
18762 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018763 }
18764
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18766 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
18767 WAIT_TIME_TDLS_MGMT);
18768
Hoonki Leed37cbb32013-04-20 00:31:14 -070018769 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
18770 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
18771
18772 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018773 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070018774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070018775 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070018776 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018777 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080018778
18779 if (pHddCtx->isLogpInProgress)
18780 {
18781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18782 "%s: LOGP in Progress. Ignore!!!", __func__);
18783 return -EAGAIN;
18784 }
Abhishek Singh837adf22015-10-01 17:37:37 +053018785 if (rc <= 0)
18786 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
18787 WLAN_LOG_INDICATOR_HOST_DRIVER,
18788 WLAN_LOG_REASON_HDD_TIME_OUT,
18789 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080018790
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018791 ret = -EINVAL;
18792 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018793 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018794 else
18795 {
18796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18797 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
18798 __func__, rc, pAdapter->mgmtTxCompletionStatus);
18799 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018800
Gopichand Nakkala05922802013-03-14 12:23:19 -070018801 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070018802 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018803 ret = max_sta_failed;
18804 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070018805 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018806
Hoonki Leea34dd892013-02-05 22:56:02 -080018807 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
18808 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018809 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018810 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18811 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018812 }
18813 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
18814 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018815 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018816 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18817 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018818 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018819
18820 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018821
18822tx_failed:
18823 /* add_station will be called before sending TDLS_SETUP_REQ and
18824 * TDLS_SETUP_RSP and as part of add_station driver will enable
18825 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
18826 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
18827 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
18828 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
18829 */
18830
18831 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18832 (SIR_MAC_TDLS_SETUP_RSP == action_code))
18833 wlan_hdd_tdls_check_bmps(pAdapter);
18834 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018835}
18836
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018837#if TDLS_MGMT_VERSION2
18838static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18839 u8 *peer, u8 action_code, u8 dialog_token,
18840 u16 status_code, u32 peer_capability,
18841 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018842#else /* TDLS_MGMT_VERSION2 */
18843#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18844static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18845 struct net_device *dev,
18846 const u8 *peer, u8 action_code,
18847 u8 dialog_token, u16 status_code,
18848 u32 peer_capability, bool initiator,
18849 const u8 *buf, size_t len)
18850#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18851static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18852 struct net_device *dev,
18853 const u8 *peer, u8 action_code,
18854 u8 dialog_token, u16 status_code,
18855 u32 peer_capability, const u8 *buf,
18856 size_t len)
18857#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18858static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18859 struct net_device *dev,
18860 u8 *peer, u8 action_code,
18861 u8 dialog_token,
18862 u16 status_code, u32 peer_capability,
18863 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018864#else
18865static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18866 u8 *peer, u8 action_code, u8 dialog_token,
18867 u16 status_code, const u8 *buf, size_t len)
18868#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018869#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018870{
18871 int ret;
18872
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018873 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018874#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018875 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18876 dialog_token, status_code,
18877 peer_capability, buf, len);
18878#else /* TDLS_MGMT_VERSION2 */
18879#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
18880 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18881 dialog_token, status_code,
18882 peer_capability, initiator,
18883 buf, len);
18884#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
18885 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18886 dialog_token, status_code,
18887 peer_capability, buf, len);
18888#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
18889 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18890 dialog_token, status_code,
18891 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018892#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018893 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18894 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018895#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018896#endif
18897 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018898
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018899 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018900}
Atul Mittal115287b2014-07-08 13:26:33 +053018901
18902int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018903#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18904 const u8 *peer,
18905#else
Atul Mittal115287b2014-07-08 13:26:33 +053018906 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018907#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018908 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053018909 cfg80211_exttdls_callback callback)
18910{
18911
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018912 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053018913 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018914 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053018915 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18916 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
18917 __func__, MAC_ADDR_ARRAY(peer));
18918
18919 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18920 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18921
18922 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018923 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18924 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18925 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018926 return -ENOTSUPP;
18927 }
18928
18929 /* To cater the requirement of establishing the TDLS link
18930 * irrespective of the data traffic , get an entry of TDLS peer.
18931 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053018932 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018933 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
18934 if (pTdlsPeer == NULL) {
18935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18936 "%s: peer " MAC_ADDRESS_STR " not existing",
18937 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053018938 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018939 return -EINVAL;
18940 }
18941
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053018942 /* check FW TDLS Off Channel capability */
18943 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053018944 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053018945 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018946 {
18947 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
18948 pTdlsPeer->peerParams.global_operating_class =
18949 tdls_peer_params->global_operating_class;
18950 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
18951 pTdlsPeer->peerParams.min_bandwidth_kbps =
18952 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018953 /* check configured channel is valid, non dfs and
18954 * not current operating channel */
18955 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
18956 tdls_peer_params->channel)) &&
18957 (pHddStaCtx) &&
18958 (tdls_peer_params->channel !=
18959 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018960 {
18961 pTdlsPeer->isOffChannelConfigured = TRUE;
18962 }
18963 else
18964 {
18965 pTdlsPeer->isOffChannelConfigured = FALSE;
18966 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18967 "%s: Configured Tdls Off Channel is not valid", __func__);
18968
18969 }
18970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018971 "%s: tdls_off_channel %d isOffChannelConfigured %d "
18972 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018973 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018974 pTdlsPeer->isOffChannelConfigured,
18975 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018976 }
18977 else
18978 {
18979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053018980 "%s: TDLS off channel FW capability %d, "
18981 "host capab %d or Invalid TDLS Peer Params", __func__,
18982 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
18983 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018984 }
18985
Atul Mittal115287b2014-07-08 13:26:33 +053018986 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
18987
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018988 mutex_unlock(&pHddCtx->tdls_lock);
18989
Atul Mittal115287b2014-07-08 13:26:33 +053018990 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18991 " %s TDLS Add Force Peer Failed",
18992 __func__);
18993 return -EINVAL;
18994 }
18995 /*EXT TDLS*/
18996
18997 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018998 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018999 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19000 " %s TDLS set callback Failed",
19001 __func__);
19002 return -EINVAL;
19003 }
19004
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019005 mutex_unlock(&pHddCtx->tdls_lock);
19006
Atul Mittal115287b2014-07-08 13:26:33 +053019007 return(0);
19008
19009}
19010
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019011int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
19012#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19013 const u8 *peer
19014#else
19015 u8 *peer
19016#endif
19017)
Atul Mittal115287b2014-07-08 13:26:33 +053019018{
19019
19020 hddTdlsPeer_t *pTdlsPeer;
19021 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019022
Atul Mittal115287b2014-07-08 13:26:33 +053019023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19024 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
19025 __func__, MAC_ADDR_ARRAY(peer));
19026
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019027 if (0 != wlan_hdd_validate_context(pHddCtx)) {
19028 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
19029 return -EINVAL;
19030 }
19031
Atul Mittal115287b2014-07-08 13:26:33 +053019032 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19033 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19034
19035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019036 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19037 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19038 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019039 return -ENOTSUPP;
19040 }
19041
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019042 mutex_lock(&pHddCtx->tdls_lock);
19043 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053019044
19045 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019046 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019047 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019048 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053019049 __func__, MAC_ADDR_ARRAY(peer));
19050 return -EINVAL;
19051 }
19052 else {
19053 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
19054 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019055 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
19056 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019057 /* if channel switch is configured, reset
19058 the channel for this peer */
19059 if (TRUE == pTdlsPeer->isOffChannelConfigured)
19060 {
19061 pTdlsPeer->peerParams.channel = 0;
19062 pTdlsPeer->isOffChannelConfigured = FALSE;
19063 }
Atul Mittal115287b2014-07-08 13:26:33 +053019064 }
19065
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019066 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019067 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019068 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053019069 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019070 }
Atul Mittal115287b2014-07-08 13:26:33 +053019071
19072 /*EXT TDLS*/
19073
19074 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019075 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19077 " %s TDLS set callback Failed",
19078 __func__);
19079 return -EINVAL;
19080 }
Atul Mittal115287b2014-07-08 13:26:33 +053019081
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019082 mutex_unlock(&pHddCtx->tdls_lock);
19083
19084 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053019085}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019086static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019087#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19088 const u8 *peer,
19089#else
19090 u8 *peer,
19091#endif
19092 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019093{
19094 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19095 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019096 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019097 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019098
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019099 ENTER();
19100
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019101 if (!pAdapter) {
19102 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
19103 return -EINVAL;
19104 }
19105
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019106 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19107 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
19108 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019109 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019110 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019111 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070019112 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019113 return -EINVAL;
19114 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019115
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019116 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019117 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019118 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019119 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019120 }
19121
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019122
19123 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019124 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019125 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019127 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
19128 "Cannot process TDLS commands",
19129 pHddCtx->cfg_ini->fEnableTDLSSupport,
19130 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019131 return -ENOTSUPP;
19132 }
19133
19134 switch (oper) {
19135 case NL80211_TDLS_ENABLE_LINK:
19136 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019137 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019138 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053019139 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
19140 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053019141 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019142 tANI_U16 numCurrTdlsPeers = 0;
19143 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019144 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019145 tSirMacAddr peerMac;
19146 int channel;
19147 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019148
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19150 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
19151 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019152
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019153 mutex_lock(&pHddCtx->tdls_lock);
19154 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019155 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053019156 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019157 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019158 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19159 " (oper %d) not exsting. ignored",
19160 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19161 return -EINVAL;
19162 }
19163
19164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19165 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19166 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19167 "NL80211_TDLS_ENABLE_LINK");
19168
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019169 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
19170 {
19171 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
19172 MAC_ADDRESS_STR " failed",
19173 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019174 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019175 return -EINVAL;
19176 }
19177
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019178 /* before starting tdls connection, set tdls
19179 * off channel established status to default value */
19180 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019181
19182 mutex_unlock(&pHddCtx->tdls_lock);
19183
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053019184 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019185 /* TDLS Off Channel, Disable tdls channel switch,
19186 when there are more than one tdls link */
19187 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053019188 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019189 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019190 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019191 /* get connected peer and send disable tdls off chan */
19192 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019193 if ((connPeer) &&
19194 (connPeer->isOffChannelSupported == TRUE) &&
19195 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019196 {
19197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19198 "%s: More then one peer connected, Disable "
19199 "TDLS channel switch", __func__);
19200
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019201 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019202 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
19203 channel = connPeer->peerParams.channel;
19204
19205 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019206
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019207 ret = sme_SendTdlsChanSwitchReq(
19208 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019209 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019210 peerMac,
19211 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019212 TDLS_OFF_CHANNEL_BW_OFFSET,
19213 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019214 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019215 hddLog(VOS_TRACE_LEVEL_ERROR,
19216 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019217 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019218 }
19219 else
19220 {
19221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19222 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019223 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019224 "isOffChannelConfigured %d",
19225 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019226 (connPeer ? (connPeer->isOffChannelSupported)
19227 : -1),
19228 (connPeer ? (connPeer->isOffChannelConfigured)
19229 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019230 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019231 }
19232 }
19233
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019234 mutex_lock(&pHddCtx->tdls_lock);
19235 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19236 if ( NULL == pTdlsPeer ) {
19237 mutex_unlock(&pHddCtx->tdls_lock);
19238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19239 "%s: " MAC_ADDRESS_STR
19240 " (oper %d) peer got freed in other context. ignored",
19241 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19242 return -EINVAL;
19243 }
19244 peer_status = pTdlsPeer->link_status;
19245 mutex_unlock(&pHddCtx->tdls_lock);
19246
19247 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019248 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019249 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053019250
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019251 if (0 != wlan_hdd_tdls_get_link_establish_params(
19252 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019253 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019254 return -EINVAL;
19255 }
19256 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019257
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019258 ret = sme_SendTdlsLinkEstablishParams(
19259 WLAN_HDD_GET_HAL_CTX(pAdapter),
19260 pAdapter->sessionId, peer,
19261 &tdlsLinkEstablishParams);
19262 if (ret != VOS_STATUS_SUCCESS) {
19263 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
19264 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019265 /* Send TDLS peer UAPSD capabilities to the firmware and
19266 * register with the TL on after the response for this operation
19267 * is received .
19268 */
19269 ret = wait_for_completion_interruptible_timeout(
19270 &pAdapter->tdls_link_establish_req_comp,
19271 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053019272
19273 mutex_lock(&pHddCtx->tdls_lock);
19274 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19275 if ( NULL == pTdlsPeer ) {
19276 mutex_unlock(&pHddCtx->tdls_lock);
19277 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19278 "%s %d: " MAC_ADDRESS_STR
19279 " (oper %d) peer got freed in other context. ignored",
19280 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
19281 (int)oper);
19282 return -EINVAL;
19283 }
19284 peer_status = pTdlsPeer->link_status;
19285 mutex_unlock(&pHddCtx->tdls_lock);
19286
19287 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019288 {
19289 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019290 FL("Link Establish Request Failed Status %ld"),
19291 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019292 return -EINVAL;
19293 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019294 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019295
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019296 mutex_lock(&pHddCtx->tdls_lock);
19297 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19298 if ( NULL == pTdlsPeer ) {
19299 mutex_unlock(&pHddCtx->tdls_lock);
19300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19301 "%s: " MAC_ADDRESS_STR
19302 " (oper %d) peer got freed in other context. ignored",
19303 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19304 return -EINVAL;
19305 }
19306
Atul Mittal115287b2014-07-08 13:26:33 +053019307 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
19308 eTDLS_LINK_CONNECTED,
19309 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019310 staDesc.ucSTAId = pTdlsPeer->staId;
19311 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053019312
19313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19314 "%s: tdlsLinkEstablishParams of peer "
19315 MAC_ADDRESS_STR "uapsdQueues: %d"
19316 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
19317 "isResponder: %d peerstaId: %d",
19318 __func__,
19319 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
19320 tdlsLinkEstablishParams.uapsdQueues,
19321 tdlsLinkEstablishParams.qos,
19322 tdlsLinkEstablishParams.maxSp,
19323 tdlsLinkEstablishParams.isBufSta,
19324 tdlsLinkEstablishParams.isOffChannelSupported,
19325 tdlsLinkEstablishParams.isResponder,
19326 pTdlsPeer->staId);
19327
19328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19329 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
19330 __func__,
19331 staDesc.ucSTAId,
19332 staDesc.ucQosEnabled);
19333
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019334 ret = WLANTL_UpdateTdlsSTAClient(
19335 pHddCtx->pvosContext,
19336 &staDesc);
19337 if (ret != VOS_STATUS_SUCCESS) {
19338 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
19339 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053019340
Gopichand Nakkala471708b2013-06-04 20:03:01 +053019341 /* Mark TDLS client Authenticated .*/
19342 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
19343 pTdlsPeer->staId,
19344 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070019345 if (VOS_STATUS_SUCCESS == status)
19346 {
Hoonki Lee14621352013-04-16 17:51:19 -070019347 if (pTdlsPeer->is_responder == 0)
19348 {
19349 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019350 tdlsConnInfo_t *tdlsInfo;
19351
19352 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
19353
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019354 if (!vos_timer_is_initialized(
19355 &pTdlsPeer->initiatorWaitTimeoutTimer))
19356 {
19357 /* Initialize initiator wait callback */
19358 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019359 &pTdlsPeer->initiatorWaitTimeoutTimer,
19360 VOS_TIMER_TYPE_SW,
19361 wlan_hdd_tdls_initiator_wait_cb,
19362 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019363 }
Hoonki Lee14621352013-04-16 17:51:19 -070019364 wlan_hdd_tdls_timer_restart(pAdapter,
19365 &pTdlsPeer->initiatorWaitTimeoutTimer,
19366 WAIT_TIME_TDLS_INITIATOR);
19367 /* suspend initiator TX until it receives direct packet from the
19368 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019369 ret = WLANTL_SuspendDataTx(
19370 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
19371 &staId, NULL);
19372 if (ret != VOS_STATUS_SUCCESS) {
19373 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
19374 }
Hoonki Lee14621352013-04-16 17:51:19 -070019375 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019376
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019377 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019378 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019379 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019380 suppChannelLen =
19381 tdlsLinkEstablishParams.supportedChannelsLen;
19382
19383 if ((suppChannelLen > 0) &&
19384 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
19385 {
19386 tANI_U8 suppPeerChannel = 0;
19387 int i = 0;
19388 for (i = 0U; i < suppChannelLen; i++)
19389 {
19390 suppPeerChannel =
19391 tdlsLinkEstablishParams.supportedChannels[i];
19392
19393 pTdlsPeer->isOffChannelSupported = FALSE;
19394 if (suppPeerChannel ==
19395 pTdlsPeer->peerParams.channel)
19396 {
19397 pTdlsPeer->isOffChannelSupported = TRUE;
19398 break;
19399 }
19400 }
19401 }
19402 else
19403 {
19404 pTdlsPeer->isOffChannelSupported = FALSE;
19405 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019406 }
19407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19408 "%s: TDLS channel switch request for channel "
19409 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019410 "%d isOffChannelSupported %d", __func__,
19411 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019412 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019413 suppChannelLen,
19414 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019415
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019416 /* TDLS Off Channel, Enable tdls channel switch,
19417 when their is only one tdls link and it supports */
19418 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19419 if ((numCurrTdlsPeers == 1) &&
19420 (TRUE == pTdlsPeer->isOffChannelSupported) &&
19421 (TRUE == pTdlsPeer->isOffChannelConfigured))
19422 {
19423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19424 "%s: Send TDLS channel switch request for channel %d",
19425 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019426
19427 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019428 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
19429 channel = pTdlsPeer->peerParams.channel;
19430
19431 mutex_unlock(&pHddCtx->tdls_lock);
19432
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019433 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
19434 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019435 peerMac,
19436 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019437 TDLS_OFF_CHANNEL_BW_OFFSET,
19438 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019439 if (ret != VOS_STATUS_SUCCESS) {
19440 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
19441 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019442 }
19443 else
19444 {
19445 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19446 "%s: TDLS channel switch request not sent"
19447 " numCurrTdlsPeers %d "
19448 "isOffChannelSupported %d "
19449 "isOffChannelConfigured %d",
19450 __func__, numCurrTdlsPeers,
19451 pTdlsPeer->isOffChannelSupported,
19452 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019453 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019454 }
19455
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070019456 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019457 else
19458 mutex_unlock(&pHddCtx->tdls_lock);
19459
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019460 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019461
19462 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019463 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
19464 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019465 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019466 int ac;
19467 uint8 ucAc[4] = { WLANTL_AC_VO,
19468 WLANTL_AC_VI,
19469 WLANTL_AC_BK,
19470 WLANTL_AC_BE };
19471 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
19472 for(ac=0; ac < 4; ac++)
19473 {
19474 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
19475 pTdlsPeer->staId, ucAc[ac],
19476 tlTid[ac], tlTid[ac], 0, 0,
19477 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019478 if (status != VOS_STATUS_SUCCESS) {
19479 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
19480 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053019481 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019482 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019483 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019484
Bhargav Shah66896792015-10-01 18:17:37 +053019485 /* stop TCP delack timer if TDLS is enable */
19486 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
19487 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053019488 hdd_wlan_tdls_enable_link_event(peer,
19489 pTdlsPeer->isOffChannelSupported,
19490 pTdlsPeer->isOffChannelConfigured,
19491 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019492 }
19493 break;
19494 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080019495 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019496 tANI_U16 numCurrTdlsPeers = 0;
19497 hddTdlsPeer_t *connPeer = NULL;
19498
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19500 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
19501 __func__, MAC_ADDR_ARRAY(peer));
19502
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019503 mutex_lock(&pHddCtx->tdls_lock);
19504 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019505
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019506
Sunil Dutt41de4e22013-11-14 18:09:02 +053019507 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019508 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019509 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19510 " (oper %d) not exsting. ignored",
19511 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19512 return -EINVAL;
19513 }
19514
19515 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19516 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19517 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19518 "NL80211_TDLS_DISABLE_LINK");
19519
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019520 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080019521 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019522 long status;
19523
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019524 /* set tdls off channel status to false for this peer */
19525 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053019526 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
19527 eTDLS_LINK_TEARING,
19528 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
19529 eTDLS_LINK_UNSPECIFIED:
19530 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019531 mutex_unlock(&pHddCtx->tdls_lock);
19532
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019533 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
19534
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019535 status = sme_DeleteTdlsPeerSta(
19536 WLAN_HDD_GET_HAL_CTX(pAdapter),
19537 pAdapter->sessionId, peer );
19538 if (status != VOS_STATUS_SUCCESS) {
19539 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
19540 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019541
19542 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
19543 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019544
19545 mutex_lock(&pHddCtx->tdls_lock);
19546 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19547 if ( NULL == pTdlsPeer ) {
19548 mutex_unlock(&pHddCtx->tdls_lock);
19549 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19550 " peer was freed in other context",
19551 __func__, MAC_ADDR_ARRAY(peer));
19552 return -EINVAL;
19553 }
19554
Atul Mittal271a7652014-09-12 13:18:22 +053019555 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053019556 eTDLS_LINK_IDLE,
19557 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019558 mutex_unlock(&pHddCtx->tdls_lock);
19559
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019560 if (status <= 0)
19561 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19563 "%s: Del station failed status %ld",
19564 __func__, status);
19565 return -EPERM;
19566 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019567
19568 /* TDLS Off Channel, Enable tdls channel switch,
19569 when their is only one tdls link and it supports */
19570 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19571 if (numCurrTdlsPeers == 1)
19572 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019573 tSirMacAddr peerMac;
19574 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019575
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019576 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019577 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019578
19579 if (connPeer == NULL) {
19580 mutex_unlock(&pHddCtx->tdls_lock);
19581 hddLog(VOS_TRACE_LEVEL_ERROR,
19582 "%s connPeer is NULL", __func__);
19583 return -EINVAL;
19584 }
19585
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019586 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
19587 channel = connPeer->peerParams.channel;
19588
19589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19590 "%s: TDLS channel switch "
19591 "isOffChannelSupported %d "
19592 "isOffChannelConfigured %d "
19593 "isOffChannelEstablished %d",
19594 __func__,
19595 (connPeer ? connPeer->isOffChannelSupported : -1),
19596 (connPeer ? connPeer->isOffChannelConfigured : -1),
19597 (connPeer ? connPeer->isOffChannelEstablished : -1));
19598
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019599 if ((connPeer) &&
19600 (connPeer->isOffChannelSupported == TRUE) &&
19601 (connPeer->isOffChannelConfigured == TRUE))
19602 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019603 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019604 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019605 status = sme_SendTdlsChanSwitchReq(
19606 WLAN_HDD_GET_HAL_CTX(pAdapter),
19607 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019608 peerMac,
19609 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019610 TDLS_OFF_CHANNEL_BW_OFFSET,
19611 TDLS_CHANNEL_SWITCH_ENABLE);
19612 if (status != VOS_STATUS_SUCCESS) {
19613 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
19614 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019615 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019616 else
19617 mutex_unlock(&pHddCtx->tdls_lock);
19618 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019619 else
19620 {
19621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19622 "%s: TDLS channel switch request not sent "
19623 "numCurrTdlsPeers %d ",
19624 __func__, numCurrTdlsPeers);
19625 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019626 }
19627 else
19628 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019629 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19631 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080019632 }
Bhargav Shah66896792015-10-01 18:17:37 +053019633 if (numCurrTdlsPeers == 0) {
19634 /* start TCP delack timer if TDLS is disable */
19635 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
19636 hdd_manage_delack_timer(pHddCtx);
19637 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019638 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019639 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019640 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019641 {
Atul Mittal115287b2014-07-08 13:26:33 +053019642 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019643
Atul Mittal115287b2014-07-08 13:26:33 +053019644 if (0 != status)
19645 {
19646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019647 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053019648 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019649 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053019650 break;
19651 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019652 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019653 {
Atul Mittal115287b2014-07-08 13:26:33 +053019654 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
19655 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019656 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053019657 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019658
Atul Mittal115287b2014-07-08 13:26:33 +053019659 if (0 != status)
19660 {
19661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019662 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053019663 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053019664 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053019665 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019666 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019667 case NL80211_TDLS_DISCOVERY_REQ:
19668 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019670 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019671 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019672 return -ENOTSUPP;
19673 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19675 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019676 return -ENOTSUPP;
19677 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019678
19679 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019680 return 0;
19681}
Chilam NG571c65a2013-01-19 12:27:36 +053019682
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019683static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019684#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19685 const u8 *peer,
19686#else
19687 u8 *peer,
19688#endif
19689 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019690{
19691 int ret;
19692
19693 vos_ssr_protect(__func__);
19694 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
19695 vos_ssr_unprotect(__func__);
19696
19697 return ret;
19698}
19699
Chilam NG571c65a2013-01-19 12:27:36 +053019700int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
19701 struct net_device *dev, u8 *peer)
19702{
Arif Hussaina7c8e412013-11-20 11:06:42 -080019703 hddLog(VOS_TRACE_LEVEL_INFO,
19704 "tdls send discover req: "MAC_ADDRESS_STR,
19705 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019706#if TDLS_MGMT_VERSION2
19707 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19708 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19709#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019710#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19711 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19712 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
19713#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19714 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19715 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19716#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19717 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19718 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19719#else
Chilam NG571c65a2013-01-19 12:27:36 +053019720 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19721 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019722#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019723#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053019724}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019725#endif
19726
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019727#ifdef WLAN_FEATURE_GTK_OFFLOAD
19728/*
19729 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
19730 * Callback rountine called upon receiving response for
19731 * get offload info
19732 */
19733void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
19734 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
19735{
19736
19737 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019738 tANI_U8 tempReplayCounter[8];
19739 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019740
19741 ENTER();
19742
19743 if (NULL == pAdapter)
19744 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019746 "%s: HDD adapter is Null", __func__);
19747 return ;
19748 }
19749
19750 if (NULL == pGtkOffloadGetInfoRsp)
19751 {
19752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19753 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
19754 return ;
19755 }
19756
19757 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
19758 {
19759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19760 "%s: wlan Failed to get replay counter value",
19761 __func__);
19762 return ;
19763 }
19764
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019765 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19766 /* Update replay counter */
19767 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
19768 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19769
19770 {
19771 /* changing from little to big endian since supplicant
19772 * works on big endian format
19773 */
19774 int i;
19775 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19776
19777 for (i = 0; i < 8; i++)
19778 {
19779 tempReplayCounter[7-i] = (tANI_U8)p[i];
19780 }
19781 }
19782
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019783 /* Update replay counter to NL */
19784 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019785 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019786}
19787
19788/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019789 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019790 * This function is used to offload GTK rekeying job to the firmware.
19791 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019792int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019793 struct cfg80211_gtk_rekey_data *data)
19794{
19795 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19796 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19797 hdd_station_ctx_t *pHddStaCtx;
19798 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019799 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019800 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019801 eHalStatus status = eHAL_STATUS_FAILURE;
19802
19803 ENTER();
19804
19805 if (NULL == pAdapter)
19806 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019808 "%s: HDD adapter is Null", __func__);
19809 return -ENODEV;
19810 }
19811
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019812 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19813 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
19814 pAdapter->sessionId, pAdapter->device_mode));
19815
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019816 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019817 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019818 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019819 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019820 }
19821
19822 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19823 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19824 if (NULL == hHal)
19825 {
19826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19827 "%s: HAL context is Null!!!", __func__);
19828 return -EAGAIN;
19829 }
19830
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019831 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
19832 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
19833 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
19834 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019835 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019836 {
19837 /* changing from big to little endian since driver
19838 * works on little endian format
19839 */
19840 tANI_U8 *p =
19841 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
19842 int i;
19843
19844 for (i = 0; i < 8; i++)
19845 {
19846 p[7-i] = data->replay_ctr[i];
19847 }
19848 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019849
19850 if (TRUE == pHddCtx->hdd_wlan_suspended)
19851 {
19852 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019853 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
19854 sizeof (tSirGtkOffloadParams));
19855 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019856 pAdapter->sessionId);
19857
19858 if (eHAL_STATUS_SUCCESS != status)
19859 {
19860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19861 "%s: sme_SetGTKOffload failed, returned %d",
19862 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019863
19864 /* Need to clear any trace of key value in the memory.
19865 * Thus zero out the memory even though it is local
19866 * variable.
19867 */
19868 vos_mem_zero(&hddGtkOffloadReqParams,
19869 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019870 return status;
19871 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19873 "%s: sme_SetGTKOffload successfull", __func__);
19874 }
19875 else
19876 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019877 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19878 "%s: wlan not suspended GTKOffload request is stored",
19879 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019880 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019881
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019882 /* Need to clear any trace of key value in the memory.
19883 * Thus zero out the memory even though it is local
19884 * variable.
19885 */
19886 vos_mem_zero(&hddGtkOffloadReqParams,
19887 sizeof(hddGtkOffloadReqParams));
19888
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019889 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019890 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019891}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019892
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019893int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
19894 struct cfg80211_gtk_rekey_data *data)
19895{
19896 int ret;
19897
19898 vos_ssr_protect(__func__);
19899 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
19900 vos_ssr_unprotect(__func__);
19901
19902 return ret;
19903}
19904#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019905/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019906 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019907 * This function is used to set access control policy
19908 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019909static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19910 struct net_device *dev,
19911 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019912{
19913 int i;
19914 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19915 hdd_hostapd_state_t *pHostapdState;
19916 tsap_Config_t *pConfig;
19917 v_CONTEXT_t pVosContext = NULL;
19918 hdd_context_t *pHddCtx;
19919 int status;
19920
19921 ENTER();
19922
19923 if (NULL == pAdapter)
19924 {
19925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19926 "%s: HDD adapter is Null", __func__);
19927 return -ENODEV;
19928 }
19929
19930 if (NULL == params)
19931 {
19932 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19933 "%s: params is Null", __func__);
19934 return -EINVAL;
19935 }
19936
19937 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19938 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019939 if (0 != status)
19940 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019941 return status;
19942 }
19943
19944 pVosContext = pHddCtx->pvosContext;
19945 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
19946
19947 if (NULL == pHostapdState)
19948 {
19949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19950 "%s: pHostapdState is Null", __func__);
19951 return -EINVAL;
19952 }
19953
19954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
19955 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019956 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19957 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
19958 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019959
19960 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
19961 {
19962 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
19963
19964 /* default value */
19965 pConfig->num_accept_mac = 0;
19966 pConfig->num_deny_mac = 0;
19967
19968 /**
19969 * access control policy
19970 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
19971 * listed in hostapd.deny file.
19972 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
19973 * listed in hostapd.accept file.
19974 */
19975 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
19976 {
19977 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
19978 }
19979 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
19980 {
19981 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
19982 }
19983 else
19984 {
19985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19986 "%s:Acl Policy : %d is not supported",
19987 __func__, params->acl_policy);
19988 return -ENOTSUPP;
19989 }
19990
19991 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
19992 {
19993 pConfig->num_accept_mac = params->n_acl_entries;
19994 for (i = 0; i < params->n_acl_entries; i++)
19995 {
19996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19997 "** Add ACL MAC entry %i in WhiletList :"
19998 MAC_ADDRESS_STR, i,
19999 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20000
20001 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
20002 sizeof(qcmacaddr));
20003 }
20004 }
20005 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
20006 {
20007 pConfig->num_deny_mac = params->n_acl_entries;
20008 for (i = 0; i < params->n_acl_entries; i++)
20009 {
20010 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20011 "** Add ACL MAC entry %i in BlackList :"
20012 MAC_ADDRESS_STR, i,
20013 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20014
20015 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
20016 sizeof(qcmacaddr));
20017 }
20018 }
20019
20020 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
20021 {
20022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20023 "%s: SAP Set Mac Acl fail", __func__);
20024 return -EINVAL;
20025 }
20026 }
20027 else
20028 {
20029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053020030 "%s: Invalid device_mode = %s (%d)",
20031 __func__, hdd_device_modetoString(pAdapter->device_mode),
20032 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020033 return -EINVAL;
20034 }
20035
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020036 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020037 return 0;
20038}
20039
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020040static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20041 struct net_device *dev,
20042 const struct cfg80211_acl_data *params)
20043{
20044 int ret;
20045 vos_ssr_protect(__func__);
20046 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
20047 vos_ssr_unprotect(__func__);
20048
20049 return ret;
20050}
20051
Leo Chang9056f462013-08-01 19:21:11 -070020052#ifdef WLAN_NL80211_TESTMODE
20053#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070020054void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070020055(
20056 void *pAdapter,
20057 void *indCont
20058)
20059{
Leo Changd9df8aa2013-09-26 13:32:26 -070020060 tSirLPHBInd *lphbInd;
20061 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053020062 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070020063
20064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020065 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070020066
c_hpothu73f35e62014-04-18 13:40:08 +053020067 if (pAdapter == NULL)
20068 {
20069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20070 "%s: pAdapter is NULL\n",__func__);
20071 return;
20072 }
20073
Leo Chang9056f462013-08-01 19:21:11 -070020074 if (NULL == indCont)
20075 {
20076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020077 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070020078 return;
20079 }
20080
c_hpothu73f35e62014-04-18 13:40:08 +053020081 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070020082 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070020083 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053020084 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070020085 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070020086 GFP_ATOMIC);
20087 if (!skb)
20088 {
20089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20090 "LPHB timeout, NL buffer alloc fail");
20091 return;
20092 }
20093
Leo Changac3ba772013-10-07 09:47:04 -070020094 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070020095 {
20096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20097 "WLAN_HDD_TM_ATTR_CMD put fail");
20098 goto nla_put_failure;
20099 }
Leo Changac3ba772013-10-07 09:47:04 -070020100 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070020101 {
20102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20103 "WLAN_HDD_TM_ATTR_TYPE put fail");
20104 goto nla_put_failure;
20105 }
Leo Changac3ba772013-10-07 09:47:04 -070020106 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070020107 sizeof(tSirLPHBInd), lphbInd))
20108 {
20109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20110 "WLAN_HDD_TM_ATTR_DATA put fail");
20111 goto nla_put_failure;
20112 }
Leo Chang9056f462013-08-01 19:21:11 -070020113 cfg80211_testmode_event(skb, GFP_ATOMIC);
20114 return;
20115
20116nla_put_failure:
20117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20118 "NLA Put fail");
20119 kfree_skb(skb);
20120
20121 return;
20122}
20123#endif /* FEATURE_WLAN_LPHB */
20124
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020125static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070020126{
20127 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
20128 int err = 0;
20129#ifdef FEATURE_WLAN_LPHB
20130 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070020131 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020132
20133 ENTER();
20134
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020135 err = wlan_hdd_validate_context(pHddCtx);
20136 if (0 != err)
20137 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020138 return err;
20139 }
Leo Chang9056f462013-08-01 19:21:11 -070020140#endif /* FEATURE_WLAN_LPHB */
20141
20142 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
20143 if (err)
20144 {
20145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20146 "%s Testmode INV ATTR", __func__);
20147 return err;
20148 }
20149
20150 if (!tb[WLAN_HDD_TM_ATTR_CMD])
20151 {
20152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20153 "%s Testmode INV CMD", __func__);
20154 return -EINVAL;
20155 }
20156
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020157 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20158 TRACE_CODE_HDD_CFG80211_TESTMODE,
20159 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070020160 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
20161 {
20162#ifdef FEATURE_WLAN_LPHB
20163 /* Low Power Heartbeat configuration request */
20164 case WLAN_HDD_TM_CMD_WLAN_HB:
20165 {
20166 int buf_len;
20167 void *buf;
20168 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080020169 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070020170
20171 if (!tb[WLAN_HDD_TM_ATTR_DATA])
20172 {
20173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20174 "%s Testmode INV DATA", __func__);
20175 return -EINVAL;
20176 }
20177
20178 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
20179 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080020180
Manjeet Singh3c577442017-02-10 19:03:38 +053020181 if (buf_len > sizeof(*hb_params)) {
20182 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
20183 buf_len);
20184 return -ERANGE;
20185 }
20186
Amar Singhal05852702014-02-04 14:40:00 -080020187 hb_params_temp =(tSirLPHBReq *)buf;
20188 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
20189 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
20190 return -EINVAL;
20191
Leo Chang9056f462013-08-01 19:21:11 -070020192 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
20193 if (NULL == hb_params)
20194 {
20195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20196 "%s Request Buffer Alloc Fail", __func__);
20197 return -EINVAL;
20198 }
20199
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053020200 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070020201 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070020202 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
20203 hb_params,
20204 wlan_hdd_cfg80211_lphb_ind_handler);
20205 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070020206 {
Leo Changd9df8aa2013-09-26 13:32:26 -070020207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20208 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070020209 vos_mem_free(hb_params);
20210 }
Leo Chang9056f462013-08-01 19:21:11 -070020211 return 0;
20212 }
20213#endif /* FEATURE_WLAN_LPHB */
20214 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20216 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070020217 return -EOPNOTSUPP;
20218 }
20219
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020220 EXIT();
20221 return err;
Leo Chang9056f462013-08-01 19:21:11 -070020222}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020223
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053020224static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
20225#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
20226 struct wireless_dev *wdev,
20227#endif
20228 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020229{
20230 int ret;
20231
20232 vos_ssr_protect(__func__);
20233 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
20234 vos_ssr_unprotect(__func__);
20235
20236 return ret;
20237}
Leo Chang9056f462013-08-01 19:21:11 -070020238#endif /* CONFIG_NL80211_TESTMODE */
20239
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020240extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020241static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020242 struct net_device *dev,
20243 int idx, struct survey_info *survey)
20244{
20245 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20246 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053020247 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020248 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053020249 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020250 v_S7_t snr,rssi;
20251 int status, i, j, filled = 0;
20252
20253 ENTER();
20254
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020255 if (NULL == pAdapter)
20256 {
20257 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20258 "%s: HDD adapter is Null", __func__);
20259 return -ENODEV;
20260 }
20261
20262 if (NULL == wiphy)
20263 {
20264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20265 "%s: wiphy is Null", __func__);
20266 return -ENODEV;
20267 }
20268
20269 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20270 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020271 if (0 != status)
20272 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020273 return status;
20274 }
20275
Mihir Sheted9072e02013-08-21 17:02:29 +053020276 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20277
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020278 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053020279 0 != pAdapter->survey_idx ||
20280 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020281 {
20282 /* The survey dump ops when implemented completely is expected to
20283 * return a survey of all channels and the ops is called by the
20284 * kernel with incremental values of the argument 'idx' till it
20285 * returns -ENONET. But we can only support the survey for the
20286 * operating channel for now. survey_idx is used to track
20287 * that the ops is called only once and then return -ENONET for
20288 * the next iteration
20289 */
20290 pAdapter->survey_idx = 0;
20291 return -ENONET;
20292 }
20293
Mukul Sharma9d5233b2015-06-11 20:28:20 +053020294 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
20295 {
20296 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20297 "%s: Roaming in progress, hence return ", __func__);
20298 return -ENONET;
20299 }
20300
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020301 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
20302
20303 wlan_hdd_get_snr(pAdapter, &snr);
20304 wlan_hdd_get_rssi(pAdapter, &rssi);
20305
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020306 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20307 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
20308 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020309 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
20310 hdd_wlan_get_freq(channel, &freq);
20311
20312
20313 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
20314 {
20315 if (NULL == wiphy->bands[i])
20316 {
20317 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
20318 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
20319 continue;
20320 }
20321
20322 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
20323 {
20324 struct ieee80211_supported_band *band = wiphy->bands[i];
20325
20326 if (band->channels[j].center_freq == (v_U16_t)freq)
20327 {
20328 survey->channel = &band->channels[j];
20329 /* The Rx BDs contain SNR values in dB for the received frames
20330 * while the supplicant expects noise. So we calculate and
20331 * return the value of noise (dBm)
20332 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
20333 */
20334 survey->noise = rssi - snr;
20335 survey->filled = SURVEY_INFO_NOISE_DBM;
20336 filled = 1;
20337 }
20338 }
20339 }
20340
20341 if (filled)
20342 pAdapter->survey_idx = 1;
20343 else
20344 {
20345 pAdapter->survey_idx = 0;
20346 return -ENONET;
20347 }
20348
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020349 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020350 return 0;
20351}
20352
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020353static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
20354 struct net_device *dev,
20355 int idx, struct survey_info *survey)
20356{
20357 int ret;
20358
20359 vos_ssr_protect(__func__);
20360 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
20361 vos_ssr_unprotect(__func__);
20362
20363 return ret;
20364}
20365
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020366/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020367 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020368 * this is called when cfg80211 driver resume
20369 * driver updates latest sched_scan scan result(if any) to cfg80211 database
20370 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020371int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020372{
20373 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
20374 hdd_adapter_t *pAdapter;
20375 hdd_adapter_list_node_t *pAdapterNode, *pNext;
20376 VOS_STATUS status = VOS_STATUS_SUCCESS;
20377
20378 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020379
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020380 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020381 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020382 return 0;
20383 }
20384
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020385 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
20386 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020387
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053020388 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020389 {
20390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20391 "%s: Resume SoftAP", __func__);
20392 hdd_set_wlan_suspend_mode(false);
20393 }
20394
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020395 spin_lock(&pHddCtx->schedScan_lock);
20396 pHddCtx->isWiphySuspended = FALSE;
20397 if (TRUE != pHddCtx->isSchedScanUpdatePending)
20398 {
20399 spin_unlock(&pHddCtx->schedScan_lock);
20400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20401 "%s: Return resume is not due to PNO indication", __func__);
20402 return 0;
20403 }
20404 // Reset flag to avoid updatating cfg80211 data old results again
20405 pHddCtx->isSchedScanUpdatePending = FALSE;
20406 spin_unlock(&pHddCtx->schedScan_lock);
20407
20408 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
20409
20410 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
20411 {
20412 pAdapter = pAdapterNode->pAdapter;
20413 if ( (NULL != pAdapter) &&
20414 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
20415 {
20416 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020417 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020418 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
20419 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020420 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020421 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020422 {
20423 /* Acquire wakelock to handle the case where APP's tries to
20424 * suspend immediately after updating the scan results. Whis
20425 * results in app's is in suspended state and not able to
20426 * process the connect request to AP
20427 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053020428 hdd_prevent_suspend_timeout(2000,
20429 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020430 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053020431 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020432
20433 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20434 "%s : cfg80211 scan result database updated", __func__);
20435
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020436 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020437 return 0;
20438
20439 }
20440 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
20441 pAdapterNode = pNext;
20442 }
20443
20444 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20445 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020446 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020447 return 0;
20448}
20449
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020450int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
20451{
20452 int ret;
20453
20454 vos_ssr_protect(__func__);
20455 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
20456 vos_ssr_unprotect(__func__);
20457
20458 return ret;
20459}
20460
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020461/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020462 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020463 * this is called when cfg80211 driver suspends
20464 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020465int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020466 struct cfg80211_wowlan *wow)
20467{
20468 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020469 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020470
20471 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020472
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020473 ret = wlan_hdd_validate_context(pHddCtx);
20474 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020475 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020476 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020477 }
20478
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053020479 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20481 "%s: Suspend SoftAP", __func__);
20482 hdd_set_wlan_suspend_mode(true);
20483 }
20484
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020485
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020486 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20487 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
20488 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020489 pHddCtx->isWiphySuspended = TRUE;
20490
20491 EXIT();
20492
20493 return 0;
20494}
20495
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020496int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
20497 struct cfg80211_wowlan *wow)
20498{
20499 int ret;
20500
20501 vos_ssr_protect(__func__);
20502 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
20503 vos_ssr_unprotect(__func__);
20504
20505 return ret;
20506}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020507
20508#ifdef FEATURE_OEM_DATA_SUPPORT
20509static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020510 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020511{
20512 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
20513
20514 ENTER();
20515
20516 if (wlan_hdd_validate_context(pHddCtx)) {
20517 return;
20518 }
20519 if (!pMsg)
20520 {
20521 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
20522 return;
20523 }
20524
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020525 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020526
20527 EXIT();
20528 return;
20529
20530}
20531
20532void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020533 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020534{
20535 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
20536
20537 ENTER();
20538
20539 if (wlan_hdd_validate_context(pHddCtx)) {
20540 return;
20541 }
20542
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020543 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020544
20545 switch(evType) {
20546 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053020547 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053020548 break;
20549 default:
20550 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
20551 break;
20552 }
20553 EXIT();
20554}
20555#endif
20556
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020557#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20558 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020559/**
20560 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
20561 * @wiphy: Pointer to wiphy
20562 * @wdev: Pointer to wireless device structure
20563 *
20564 * This function is used to abort an ongoing scan
20565 *
20566 * Return: None
20567 */
20568static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20569 struct wireless_dev *wdev)
20570{
20571 struct net_device *dev = wdev->netdev;
20572 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
20573 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
20574 int ret;
20575
20576 ENTER();
20577
20578 if (NULL == adapter) {
20579 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
20580 return;
20581 }
20582
20583 ret = wlan_hdd_validate_context(hdd_ctx);
20584 if (0 != ret)
20585 return;
20586
20587 wlan_hdd_scan_abort(adapter);
20588
20589 return;
20590}
20591
20592/**
20593 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
20594 * @wiphy: Pointer to wiphy
20595 * @wdev: Pointer to wireless device structure
20596 *
20597 * Return: None
20598 */
20599void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20600 struct wireless_dev *wdev)
20601{
20602 vos_ssr_protect(__func__);
20603 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
20604 vos_ssr_unprotect(__func__);
20605
20606 return;
20607}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020608#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020609
Jeff Johnson295189b2012-06-20 16:38:30 -070020610/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020611static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070020612{
20613 .add_virtual_intf = wlan_hdd_add_virtual_intf,
20614 .del_virtual_intf = wlan_hdd_del_virtual_intf,
20615 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
20616 .change_station = wlan_hdd_change_station,
20617#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
20618 .add_beacon = wlan_hdd_cfg80211_add_beacon,
20619 .del_beacon = wlan_hdd_cfg80211_del_beacon,
20620 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020621#else
20622 .start_ap = wlan_hdd_cfg80211_start_ap,
20623 .change_beacon = wlan_hdd_cfg80211_change_beacon,
20624 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070020625#endif
20626 .change_bss = wlan_hdd_cfg80211_change_bss,
20627 .add_key = wlan_hdd_cfg80211_add_key,
20628 .get_key = wlan_hdd_cfg80211_get_key,
20629 .del_key = wlan_hdd_cfg80211_del_key,
20630 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020631#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070020632 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020633#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020634 .scan = wlan_hdd_cfg80211_scan,
20635 .connect = wlan_hdd_cfg80211_connect,
20636 .disconnect = wlan_hdd_cfg80211_disconnect,
20637 .join_ibss = wlan_hdd_cfg80211_join_ibss,
20638 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
20639 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
20640 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
20641 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070020642 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
20643 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053020644 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070020645#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
20646 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
20647 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
20648 .set_txq_params = wlan_hdd_set_txq_params,
20649#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020650 .get_station = wlan_hdd_cfg80211_get_station,
20651 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
20652 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020653 .add_station = wlan_hdd_cfg80211_add_station,
20654#ifdef FEATURE_WLAN_LFR
20655 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
20656 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
20657 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
20658#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070020659#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
20660 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
20661#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020662#ifdef FEATURE_WLAN_TDLS
20663 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
20664 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
20665#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020666#ifdef WLAN_FEATURE_GTK_OFFLOAD
20667 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
20668#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020669#ifdef FEATURE_WLAN_SCAN_PNO
20670 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
20671 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
20672#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020673 .resume = wlan_hdd_cfg80211_resume_wlan,
20674 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020675 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070020676#ifdef WLAN_NL80211_TESTMODE
20677 .testmode_cmd = wlan_hdd_cfg80211_testmode,
20678#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020679 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020680#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20681 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020682 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020683#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020684};
20685